WPF Data Binding 及经典应用示例
什么是Data Binding(数据绑定)?
Data Binding是WPF中的核心机制,它建立了UI元素(视图)与数据对象(模型/视图模型)之间的连接通道,实现了数据的自动同步。当数据发生变化时,UI自动更新;当用户修改UI时,数据也相应更新。
Data Binding的核心概念
-
绑定源(Source):提供数据的对象
-
绑定目标(Target):显示数据的UI元素(必须是DependencyProperty)
-
绑定路径(Path):指定绑定源中的属性
-
绑定模式(Binding Mode):
-
OneWay:源→目标
-
TwoWay:源⇄目标
-
OneWayToSource:目标→源
-
OneTime:仅初始化时绑定一次
-
基本语法
<TextBox Text="{Binding Path=UserName, Mode=TwoWay}" />
经典应用示例
示例1:简单属性绑定
// 数据类
public class Person : INotifyPropertyChanged
{private string _name;public string Name{get { return _name; }set { _name = value; OnPropertyChanged(); }}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged([CallerMemberName] string name = null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));}
}
<!-- XAML绑定 -->
<Window.DataContext><local:Person Name="张三"/>
</Window.DataContext><StackPanel><TextBox Text="{Binding Name, Mode=TwoWay}"/><TextBlock Text="{Binding Name}"/>
</StackPanel>
示例2:集合绑定(ListBox/ListView)
public class ProductList : ObservableCollection<Product>
{public ProductList(){Add(new Product() { Name="笔记本", Price=5999});Add(new Product() { Name="手机", Price=3999});}
}public class Product : INotifyPropertyChanged
{// 实现INotifyPropertyChanged...public string Name { get; set; }public decimal Price { get; set; }
}
<ListBox ItemsSource="{Binding}" DisplayMemberPath="Name"/>
示例3:主从绑定(Master-Detail)
<Grid><Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="2*"/></Grid.ColumnDefinitions><!-- 主表 --><ListBox ItemsSource="{Binding Employees}" DisplayMemberPath="LastName"SelectedItem="{Binding SelectedEmployee}"/><!-- 从表详情 --><StackPanel Grid.Column="1" DataContext="{Binding SelectedEmployee}"><TextBox Text="{Binding FirstName, Mode=TwoWay}"/><TextBox Text="{Binding LastName, Mode=TwoWay}"/></StackPanel>
</Grid>
示例4:数据转换(ValueConverter)
public class BoolToVisibilityConverter : IValueConverter
{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){return (bool)value ? Visibility.Visible : Visibility.Collapsed;}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){return (Visibility)value == Visibility.Visible;}
}
<Window.Resources><local:BoolToVisibilityConverter x:Key="BoolToVisibility"/>
</Window.Resources><Button Content="提交" Visibility="{Binding IsValid, Converter={StaticResource BoolToVisibility}}"/>
示例5:命令绑定(Command Binding)
public class RelayCommand : ICommand
{private Action<object> _execute;public RelayCommand(Action<object> execute){_execute = execute;}public bool CanExecute(object parameter) => true;public event EventHandler CanExecuteChanged;public void Execute(object parameter){_execute(parameter);}
}public class ViewModel
{public ICommand SaveCommand { get; }public ViewModel(){SaveCommand = new RelayCommand(ExecuteSave);}private void ExecuteSave(object param){// 保存逻辑}
}
<Button Content="保存" Command="{Binding SaveCommand}"/>
高级绑定技巧
-
RelativeSource绑定:绑定到相对元素
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"/>
-
ElementName绑定:绑定到命名元素
<Slider x:Name="slider" Minimum="0" Maximum="100"/>
<TextBlock Text="{Binding ElementName=slider, Path=Value}"/>
-
多绑定(MultiBinding)
<TextBlock><TextBlock.Text><MultiBinding StringFormat="{}{0} - {1}"><Binding Path="FirstName"/><Binding Path="LastName"/></MultiBinding></TextBlock.Text>
</TextBlock>
最佳实践
-
始终为可变数据实现INotifyPropertyChanged
-
对集合使用ObservableCollection<T>
-
考虑使用MVVM模式组织代码
-
对复杂转换使用ValueConverter
-
对用户交互使用Command绑定而非事件处理程序
Data Binding是WPF强大灵活性的核心,合理使用可以极大减少代码量,提高可维护性,实现真正的数据与UI分离。