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; }
}
相关推荐
多巴胺耐受2 小时前
【WPF】炫酷的科技报警弹窗
科技·c#·wpf
Xin_ye100865 小时前
C# 零基础到精通教程 - WPF 专题二:数据绑定与 MVVM
开发语言·c#·wpf
Xin_ye100865 小时前
C# 零基础到精通教程 - WPF 专题一:WPF 入门与 XAML 基础
c#·wpf
qq_431280705 小时前
生成解决方案将文件生成到根目录或指定文件夹下
wpf
周杰伦fans1 天前
掌握 MVVM Light:.NET 桌面应用开发的 MVVM 利器,掌握 ObservableObject、RelayCommand 和 Messenger
c#·wpf
Ws_1 天前
WPF 面试题 + 参考答案,偏 C# 桌面端开发高频。
开发语言·c#·wpf
LCG元2 天前
现代Web应用高可用架构设计与性能调优实战
前端·wpf
小二·2 天前
向量数据库深度对比:PGVector vs Qdrant vs Milvus vs Chroma(附性能测试数据)
数据库·wpf·milvus
周杰伦fans3 天前
WPF TextBlock 中 Run 元素实战——从密码强度检测到 MVVM 绑定
wpf
largecode4 天前
座机号码认证如何操作?申请热线实名名片,树立统一官方客服形象
linux·sql·华为·c#·.net·wpf·harmonyos