WPF UserControl绑定的一个需要注意的地方
注意绑定的模式尽量设为Mode=TwoWay ,UpdateSourceTrigger=PropertyChanged,这样才能激发ViewModel里面的PropertyChanged事件
UserControl代码
1 <UserControl 2 x:Class="UserControl绑定.TitleTextBox" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:UserControl绑定" 7 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 8 d:DesignHeight="450" 9 d:DesignWidth="800" 10 mc:Ignorable="d"> 11 <Grid> 12 <Grid.ColumnDefinitions> 13 <ColumnDefinition Width="3*" /> 14 <ColumnDefinition Width="7*" /> 15 </Grid.ColumnDefinitions> 16 <TextBlock Grid.Column="0" Text="{Binding Path=Title, RelativeSource={RelativeSource AncestorType=local:TitleTextBox, Mode=FindAncestor}}" /> 17 <TextBox Grid.Column="1" Text="{Binding Path=Text, RelativeSource={RelativeSource AncestorType=local:TitleTextBox, Mode=FindAncestor}}" /> 18 </Grid> 19 </UserControl>
后台
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 16 namespace UserControl绑定 17 { 18 /// <summary> 19 /// TitleTextBox.xaml 的交互逻辑 20 /// </summary> 21 public partial class TitleTextBox : UserControl 22 { 23 // Using a DependencyProperty as the backing store for Title. This enables animation, styling, binding, etc... 24 public static readonly DependencyProperty TitleProperty = 25 DependencyProperty.Register("Title", typeof(string), typeof(TitleTextBox), new PropertyMetadata(default)); 26 27 // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc... 28 public static readonly DependencyProperty TextProperty = 29 DependencyProperty.Register("Text", typeof(string), typeof(TitleTextBox), new PropertyMetadata(default)); 30 31 public string Title 32 { 33 get { return (string)GetValue(TitleProperty); } 34 set { SetValue(TitleProperty, value); } 35 } 36 37 public string Text 38 { 39 get { return (string)GetValue(TextProperty); } 40 set { SetValue(TextProperty, value); } 41 } 42 43 public TitleTextBox() 44 { 45 InitializeComponent(); 46 } 47 } 48 }
Vm代码
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using System.Windows; 8 9 namespace UserControl绑定 10 { 11 public class MainViewModel : INotifyPropertyChanged 12 { 13 private string _name; 14 15 private string _nickName; 16 17 private string _displayInfo; 18 19 public string Name 20 { 21 get => _name; 22 23 set 24 { 25 _nickName = value; 26 Raise(nameof(Name)); 27 } 28 } 29 30 public string NickName 31 { 32 get => _nickName; 33 34 set 35 { 36 _nickName = value; 37 Raise(nameof(NickName)); 38 } 39 } 40 41 public string DisplayInfo 42 { 43 get => _displayInfo; 44 45 set 46 { 47 _displayInfo = value; 48 Raise(nameof(DisplayInfo)); 49 } 50 } 51 52 public MainViewModel() 53 { 54 PropertyChanged += (s, e) => 55 { 56 MessageBox.Show("属性被更改!"); 57 }; 58 } 59 60 public event PropertyChangedEventHandler PropertyChanged; 61 62 public void Raise(string name) 63 { 64 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 65 } 66 } 67 }
界面代码
1 <Window 2 x:Class="UserControl绑定.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:UserControl绑定" 7 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 8 Title="MainWindow" 9 Width="800" 10 Height="450" 11 mc:Ignorable="d"> 12 <Window.DataContext> 13 <local:MainViewModel /> 14 </Window.DataContext> 15 <Grid> 16 <StackPanel 17 HorizontalAlignment="Center" 18 VerticalAlignment="Center" 19 Orientation="Vertical"> 20 <local:TitleTextBox 21 Title="Name:" 22 MinWidth="240" 23 Text="{Binding Name, UpdateSourceTrigger=LostFocus}" /> 24 <local:TitleTextBox 25 Title="NickName:" 26 MinWidth="240" 27 Margin="0,5" 28 Text="{Binding NickName, UpdateSourceTrigger=LostFocus}" /> 29 <local:TitleTextBox 30 Title="DisplayInfo:" 31 MinWidth="240" 32 Text="{Binding DisplayInfo, UpdateSourceTrigger=LostFocus}" /> 33 </StackPanel> 34 </Grid> 35 </Window>
测试一下
可以看到,并没有激活VM中的事件
把Mode改变一下
再次测试
这次能够触发事件了