WPF(数据绑定)

 数据绑定把数据从.NET对象传递给UI,或从UI传递给.NET对象。简单对象可以绑定到UI元素、对象列表和XAML元素上。在WPF数据绑定中,目标可以是WPF元素的任意依赖属性,CLR对象的每个属性都可以绑定源。因为WPF元素作为.NET类实现,所以每个WPF元素也可以用作绑定源。

Binding对象支持源与目标之间的几种绑定模式。绑定可以是单向的,即从源信息指向目标,但如果用户在用户界面上修改了该信息,则源不会更新。要更新源,需要双向绑定。

绑定模式说明
一次性绑定从源指向目标,且仅在应用程序启动时,或数据环境改变时绑定一次。通过这种模式可以获得数据的快照
单向

绑定从源指向目标,这对于只读数据很有用,因为它不能从用户界面中修改数据。

要更新用户界面,源必须实现INotifyPropertyChanged接口

双向

在双向绑定中,用户可以从UI中修改数据。绑定是双向的--从源指向目标,从目标指向源。

源对象需要实现读写属性,才能把改动的内容从UI更新到源对象上

指向源的单向采用这种绑定模式,如果目标属性改变,源对象也会更新

建立一个Book类用于数据绑定的源: 

public class Book
{
    public string Title { get; set; }

    public string Publisher { get; set; }

    public string Isbn { get; set; }

    public override string ToString()
    {
        return $"{Title},{Publisher},{Isbn}";
    }
}

建立一个自定义控件BookUC,将数据上下文设置为Book,然后将Book的几个属性绑定到TextBox控件上: 

<UserControl x:Class="WpfAppLearn2.BookUC"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfAppLearn2"
             mc:Ignorable="d" 
             DataContext="Book" Width="200" Height="100">
    <Grid>
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FFC1BABA" Offset="0"/>
                <GradientStop Color="#FFB47474" Offset="1"/>
            </LinearGradientBrush>
        </Grid.Background>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Label Content="Title" VerticalAlignment="Center" Margin="0" HorizontalAlignment="Right"/>
        <Label Content="Publisher" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0" Grid.Row="1"/>
        <Label Content="Isbn" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0" Grid.Row="2"/>
        <TextBox Text="{Binding Title}" VerticalAlignment="Center" Grid.Column="1" Margin="0,0,5,0"/>
        <TextBox Text="{Binding Publisher}" VerticalAlignment="Center" Grid.Column="1" Margin="0,0,5,0" Grid.Row="1"/>
        <TextBox Text="{Binding Isbn}" VerticalAlignment="Center" Grid.Column="1" Margin="0,0,5,0" Grid.Row="2"/>
        <StackPanel  Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0">
            <Button Content="Show Book" Margin="5,2" Click="Button_Click"/>
        </StackPanel>
    </Grid>
</UserControl>
/// <summary>
/// BookUC.xaml 的交互逻辑
/// </summary>
public partial class BookUC : UserControl
{
    public BookUC()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Book book = this.DataContext as Book;
        MessageBox.Show(book.ToString());
    }
}

也可以通过代码绑定数据:

public BookUC()
{
    InitializeComponent();

    //对于派生自FrameworkElement的元素,可以使用SetBinding方法绑定源
    this.tbTitle.SetBinding(TextBox.TextProperty, new Binding("Title"));
    this.tbPublisher.SetBinding(TextBox.TextProperty, new Binding("Publisher"));
    this.tbIsbn.SetBinding(TextBox.TextProperty, new Binding("Isbn"));

    //对于其他元素,可以使用辅助类BindingOperations
    BindingOperations.SetBinding(this.tbTitle, TextBox.TextProperty, new Binding("Title"));
    BindingOperations.SetBinding(this.tbPublisher, TextBox.TextProperty, new Binding("Publisher"));
    BindingOperations.SetBinding(this.tbIsbn, TextBox.TextProperty, new Binding("Isbn"));
}

若是想当在代码中修改了资源的值,也更新到界面上时,必须继承 INotifyPropertyChanged接口,如下例:

using System.ComponentModel;
public class Book : INotifyPropertyChanged
{
    string _title;
    string _publisher;
    string _isbn;

    public string Title
    {
        get { return _title; }
        set
        {
            _title = value;
            propertyChanged(nameof(Title));
        }
    }

    public string Publisher
    {
        get { return _publisher; }
        set
        {
            _publisher = value;
            propertyChanged(nameof(Publisher));
        }
    }

    public string Isbn
    {
        get { return _isbn; }
        set
        {
            _isbn = value;
            propertyChanged(nameof(Isbn));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    void propertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public override string ToString()
    {
        return $"{Title},{Publisher},{Isbn}";
    }
}

posted @ 2022-04-12 22:46  Bridgebug  阅读(208)  评论(0编辑  收藏  举报