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));
}