WPF - 尝试使用 INotifyPropertyChanged 从文本框更新中更新标签
WPF - trying to update a label from a textbox update using INotifyPropertyChanged
我已经深入研究了 WPF 和绑定的魔力和奥秘。一切顺利,然后我碰壁了,需要请那些比我聪明得多的人帮忙。
我将其缩减为一个简单的应用程序,删除了我代码中的所有其他项目。 UI 有一个文本框和一个标签。当文本框中的文本发生变化时,我想更新标签。我在某处遗漏了一个 link,我猜这是绑定,因为我似乎从未进入过集合。这是代码
Mainwindow.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));
}
}
}
}
Mainwindow.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>
感谢您的帮助
您没有绑定文本框的文本属性。它应该如下所示,其中 UpdateSourceTrigger 确保在您输入文本框时立即更新源 属性。
<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
事件是否为空,通常使用空传播运算符 ?.
:
private void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
我已经深入研究了 WPF 和绑定的魔力和奥秘。一切顺利,然后我碰壁了,需要请那些比我聪明得多的人帮忙。
我将其缩减为一个简单的应用程序,删除了我代码中的所有其他项目。 UI 有一个文本框和一个标签。当文本框中的文本发生变化时,我想更新标签。我在某处遗漏了一个 link,我猜这是绑定,因为我似乎从未进入过集合。这是代码
Mainwindow.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));
}
}
}
}
Mainwindow.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>
感谢您的帮助
您没有绑定文本框的文本属性。它应该如下所示,其中 UpdateSourceTrigger 确保在您输入文本框时立即更新源 属性。
<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
事件是否为空,通常使用空传播运算符 ?.
:
private void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}