使用 Fody.PropertyChanged 将文本添加到文本框时,为什么我的按钮没有启用?

Why isn't my button enabling when text is added to the textbox with Fody.PropertyChanged?

我正在使用 Fody.PropertyChanged 来尝试减少我的 WPF 项目中的一些样板代码。

当我尝试创建按钮单击事件时,Fody 似乎不会像处理标签和字符串之间的绑定那样处理此事件 属性。

我有一个文本框,我想根据这个文本框是否有文本来启用/禁用一个按钮。我的 XAML 看起来像:

<Window x:Class="MyProject.View.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:MyProject"
        mc:Ignorable="d">
   <Label Content="Enter text:" HorizontalAlignment="Left" Margin="21,43,0,0" VerticalAlignment="Top"/>

   <TextBox Height="100" 
      TextWrapping="Wrap" 
      Text="{Binding Test}" 
      VerticalAlignment="Top" 
      Padding="5, 3, 1, 1"
      AcceptsReturn="True" Margin="161,10,10,0"/>

   <Button Content="Go" 
      IsEnabled="{Binding Path=GoButtonIsEnabled}"
      Command="{Binding Path=ButtonClick}"
      HorizontalAlignment="Left" 
      Margin="64,158,0,0" 
      VerticalAlignment="Top" Width="75"/>
</Window>

它绑定的ViewModel是:

class MainWindowViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public ButtonCommandBinding ButtonClick { get; set; }
    public bool GoButtonIsEnabled => !String.IsNullOrWhiteSpace(Test);

    public string Test { get; set; }

    public MainWindowViewModel()
    {
        ButtonClick = new ButtonCommandBinding(OnGoButtonClick);
    }

    private void OnGoButtonClick()
    {
        System.Windows.MessageBox.Show("Hello, world!");
    }

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

ButtonCommandBinding:

public class ButtonCommandBinding : ICommand
{
    private readonly Action handler;
    private bool isEnabled;

    public ButtonCommandBinding(Action handler)
    {
        this.handler = handler;
    }

    public bool IsEnabled
    {
        get { return isEnabled; }
        set
        {
            if (value != isEnabled)
            {
                isEnabled = value;
                CanExecuteChanged?.Invoke(this, EventArgs.Empty);
            }
        }
    }

    public bool CanExecute(object parameter)
    {
        return IsEnabled;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        if (IsEnabled)
        {
            handler();
        }
    }
}

我相信在文本框中输入没有启用按钮的原因是因为 属性 更改的通知程序没有被调用..但我没有调用它是因为我正在使用 Fody。在我尝试让按钮点击工作之前,我没有在我的 ViewModel 中实现 NotifyPropertyChanged ;在实现按钮点击之前,这是由 Fody 处理的(当我只是将标签绑定到文本时)。

所以我有两个问题:

  1. 我是否误解或严重误用了 Fody 的目的?
  2. 当测试 属性 不再为空或空白时,为什么按钮不启用?

编辑:感谢 ANu 告诉我添加 [AlsoNotifyFor(nameof(GoButtonIsEnabled))] 属性。但是,我现在遇到的问题是,当我加载带有 ViewModel 中设置的文本的文本框时:

public MainWindowViewModel()
{
    Test = "Enter text here";
    ButtonClick = new ButtonCommandBinding(OnButtonClick);
    ButtonClick.IsEnabled = true;
}

...我 运行 应用程序,然后从文本框中删除文本,“前往”按钮在我单击它之前不会禁用。单击它后,操作不会 运行(因为它不应该,因为文本框是空的)并且按钮被禁用。当我在文本框中输入文本时,它不会重新启用。

似乎绑定仍然无法正常工作。

public bool GoButtonIsEnabled => !String.IsNullOrWhiteSpace(Test);

[AlsoNotifyFor(nameof(GoButtonIsEnabled))]
public string Test { get; set; }

public MainWindowViewModel()
{
    Test = "Enter text";
    ButtonClick = new ButtonCommandBinding(OnButtonClick);
    ButtonClick.IsEnabled = true;
}

XAML:

<Button Content="Go" 
   IsEnabled="{Binding Path=GoButtonIsEnabled}"
   Command="{Binding Path=ButtonClick}"
   HorizontalAlignment="Left" 
   Margin="64,158,0,0" 
   VerticalAlignment="Top" Width="75"/>

Fody 会根据需要为每个 属性 注入通知代码。但是,您还想在另一个 属性(Text) 发生更改时通知依赖的 属性(GoButtonIsEnabled)..

您需要使用 AlsoNotifyFor 属性来允许注入指向不同 属性.

的通知代码
[AlsoNotifyFor(nameof(GoButtonIsEnabled ))]
public string Test { get; set; }