WPF数据绑定

数据绑定是一个很强大且优雅的技能,之前用过好多次,但有些地方总不是特别清晰,常常需要重新翻阅资料来回顾,于是这次用了几天时间好好梳理一下,记录一下。

首先数据绑定对数据对象的要求:需要是公有属性(不支持字段和私有属性)。

如果需要在数据内容发生变化时自动更新到控件,则需要实现INotifyPropertyChanged接口,其包含 PropertyChanged事件,在属性变化时引发PropertyChanged事件。

如果绑定对象为集合时,需要在集合内容发生变化时自动更新到控件,则需要INotifyCollectionChanged接口,其包含CollectionChanged事件,目前内置的泛型集合 ObservableCollection 实现了该接口。

通常在设置绑定时,我们需要指定数据上下文,DataContext,如果控件没有设置DataContext,则会去找父容器的DataContext,依层级依次查找。也有些控件直接在代码中指定ItemsSource的。如果要绑定的数据依赖于另外一个控件的值,可以在DataContext中,绑定到另外一个控件的选中项,然后设置该控件的数据源或者绑定值。

MainWindow.xaml

cs 复制代码
<Window x:Class="TestBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestBinding"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel Name="parentContainer">
        <StackPanel Orientation="Horizontal">
            <TextBlock>BindData:</TextBlock>
            <TextBox Text="{Binding Path=BindData}"></TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock>BindDatas:</TextBlock>
            <ListBox Name="exchangeListBox" ItemsSource="{Binding Path=Exchanges}" DisplayMemberPath="ExchangeID"></ListBox>
        </StackPanel>
        <StackPanel>
            <ComboBox Name="instrumentCombbox" DataContext="{Binding ElementName=exchangeListBox, Path=SelectedItem}" ItemsSource="{Binding Path=Instruments}" DisplayMemberPath="InstrumentID"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=instrumentCombbox, Path=SelectedItem}">
            <TextBlock>ExchangeID:</TextBlock>
            <TextBox Text="{Binding Path=ExchangeID}"></TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=instrumentCombbox, Path=SelectedItem}">
            <TextBlock>InstrumentID:</TextBlock>
            <TextBox Text="{Binding Path=InstrumentID}"></TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=instrumentCombbox, Path=SelectedItem}">
            <TextBlock>InstrumentName:</TextBlock>
            <TextBox Text="{Binding Path=InstrumentName}"></TextBox>
        </StackPanel>
    </StackPanel>
</Window>

MainWindow.xaml.cs

cs 复制代码
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;

namespace TestBinding;

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    protected virtual bool SetProperty<T>(ref T member, T value, [CallerMemberName] string? propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(member, value))
        {
            return false;
        }
        member = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}
public class ExchangeViewModel : ViewModelBase
{
    private string exchangeID = string.Empty;
    public string ExchangeID { get => exchangeID; set => SetProperty(ref exchangeID, value); }
    public ObservableCollection<InstrumentViewModel> Instruments { get; set; } = new ObservableCollection<InstrumentViewModel>();
}
public class InstrumentViewModel : ViewModelBase
{
    public InstrumentViewModel(string exchangeID, string instrumentID, string instrumentName)
    {
        ExchangeID = exchangeID;
        InstrumentID = instrumentID;
        InstrumentName = instrumentName;
    }

    private string _exchangeID = string.Empty;
    private string _instrumentID = string.Empty;
    private string _instrumentName = string.Empty;
    public string ExchangeID { get => _exchangeID; set => SetProperty(ref _exchangeID, value); }
    public string InstrumentID { get => _instrumentID; set => SetProperty(ref _instrumentID, value); }
    public string InstrumentName { get => _instrumentName; set => SetProperty(ref _instrumentName, value); }
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        parentContainer.DataContext = this;

        Exchanges = new();
        ExchangeViewModel exchange1 = new ExchangeViewModel();
        exchange1.ExchangeID = "SHSE";
        exchange1.Instruments.Add(new InstrumentViewModel("SHSE", "601155", "新城控股"));
        exchange1.Instruments.Add(new InstrumentViewModel("SHSE", "600036", "招商银行"));
        exchange1.Instruments.Add(new InstrumentViewModel("SHSE", "600266", "城建发展"));
        exchange1.Instruments.Add(new InstrumentViewModel("SHSE", "600837", "海通证券"));
        exchange1.Instruments.Add(new InstrumentViewModel("SHSE", "601668", "中国建筑"));
        ExchangeViewModel exchange2 = new ExchangeViewModel();
        exchange2.ExchangeID = "SZSE";
        exchange2.Instruments.Add(new InstrumentViewModel("SZSE", "000002", "万科A"));
        exchange2.Instruments.Add(new InstrumentViewModel("SZSE", "000001", "平安银行"));
        exchange2.Instruments.Add(new InstrumentViewModel("SZSE", "000623", "吉林敖东"));
        exchange2.Instruments.Add(new InstrumentViewModel("SZSE", "002739", "万达电影"));
        exchange2.Instruments.Add(new InstrumentViewModel("SZSE", "300642", "透景生命"));


        Exchanges.Add(exchange1);
        Exchanges.Add(exchange2);
    }

    public string BindData { get; set; } = "BindData";
    public ObservableCollection<ExchangeViewModel> Exchanges { get; set; }
}
相关推荐
暮雪倾风13 分钟前
【WPF开发】控件介绍-Grid(网格布局)
windows·wpf
芝麻科技1 天前
使用ValueConverters扩展实现枚举控制页面的显示
wpf·prism
笑非不退2 天前
Wpf Image 展示方式 图片处理 显示
开发语言·javascript·wpf
△曉風殘月〆2 天前
在WPF中实现多语言切换的四种方式
wpf·多语言切换
笑非不退2 天前
WPF C# 读写嵌入的资源 JSON PNG JPG JPEG 图片等资源
c#·wpf
He BianGu2 天前
演示:基于WPF的DrawingVisual开发的频谱图和律动图
wpf·示波器·曲线图·频谱分析仪·频谱图·高性能曲线·自绘
笑非不退5 天前
WPF 设计属性 设计页面时实时显示 页面涉及集合时不显示处理 设计页面时显示集合样式 显示ItemSource TabControl等集合样式
wpf
△曉風殘月〆6 天前
WPF中的XAML详解
wpf·xaml
ithouse6 天前
使用WPF实现一个快速切换JDK版本的客户端工具
java·开发语言·wpf
河西石头6 天前
WPF之UI进阶--控件样式与样式模板及词典
ui·wpf·样式·模板·控件样式·样式模板·样式词典