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}";
}
}