使用 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 处理的(当我只是将标签绑定到文本时)。
所以我有两个问题:
- 我是否误解或严重误用了 Fody 的目的?
- 当测试 属性 不再为空或空白时,为什么按钮不启用?
编辑:感谢 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; }
我正在使用 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 处理的(当我只是将标签绑定到文本时)。
所以我有两个问题:
- 我是否误解或严重误用了 Fody 的目的?
- 当测试 属性 不再为空或空白时,为什么按钮不启用?
编辑:感谢 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; }