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改变一下

 

再次测试

这次能够触发事件了 

posted @ 2021-12-27 16:54  只吃肉不喝酒  阅读(242)  评论(0编辑  收藏  举报