WPF-尝试使用INotifyPropertyChanged从文本框更新中更新标签



我深入研究了WPF和绑定的魔力和神秘性。一切都很顺利,然后我遇到了一堵砖墙,需要向那些比我聪明得多的人寻求帮助。

我把它简化为一个简单的应用程序,删除了代码中的所有其他项目。UI有一个文本框和一个标签。当文本框中的文本发生更改时,我想更新标签。在某个地方,我错过了一个环节,我想这是束缚,因为我似乎从来没有进入过片场。这是代码

主窗口.xaml.cs

using System.ComponentModel;
using System.Windows;
namespace Databinding3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
private string myBindedVal = "...."; 
public MainWindow()
{
InitializeComponent();

}

//Create properties for our variable _myBindedVal
public string MyBindedVal
{
get => myBindedVal;

set 
{
NotifyPropertyChanged(nameof(MyBindedVal));
myBindedVal = value;
}
}
public event PropertyChangedEventHandler PropertyChanged;

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

主窗口.xml

<Window x:Class="Databinding3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Databinding3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBox x:Name="txtbx_name" Text="Textbox" HorizontalAlignment="Center" Height="57" TextWrapping="Wrap" VerticalAlignment="Center" Width="594"/>
<Label Content="{Binding MyBindedVal,   RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" HorizontalAlignment="Center" Height="44" Grid.Row="1" VerticalAlignment="Center" Width="594"/>
</Grid>
</Window>

感谢您的帮助

您没有绑定TextBox的Text属性。它应该如下所示,其中UpdateSourceTrigger确保在您键入TextBox时立即更新源属性。

<TextBox Text="{Binding MyBoundVal, UpdateSourceTrigger=PropertyChanged}" .../>

上面的Binding没有明确指定源对象,因此使用Window的DataContext作为源。设置DataContext如下:

public MainWindow()
{
InitializeComponent();
DataContext = this;
}

标签绑定将只是

<Label Content="{Binding MyBoundVal}" .../>

请注意,您通常会使用TextBlock而不是Label来显示文本:

<TextBlock Text="{Binding MyBoundVal}" .../>

属性setter中的执行顺序也很重要。在激发PropertyChanged事件之前,先分配后备字段值。

public string MyBoundVal
{
get => myBoundVal;
set 
{
myBoundVal = value;
NotifyPropertyChanged(nameof(MyBoundVal));
}
}

最后,NotifyPropertyChanged方法应该如下所示。测试propertyName参数毫无意义,但您应该测试PropertyChanged事件的null,通常使用null传播运算符?.:

private void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

最新更新