WPF ICommands 绑定
WPF ICommands Binding
我将继续探索 WPF 并尝试使用命令来遵循 MVVM。
我的简单代码如下。
MainWindow.xaml
<Window x:Class="ClickCommand.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:ClickCommand"
xmlns:vm="clr-namespace:ClickCommand.ViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<vm:ButtonViewModel x:Key="ViewModel"/>
</Window.Resources>
<Grid>
<StackPanel Width="350" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Vertical">
<Button Height="80" FontSize="32" Background="LightBlue" Content="Click Me"
Command="{Binding ButtonCommand, Source={StaticResource ViewModel}}"/>
<TextBox x:Name="textBoxTest" Margin="5" FontSize="36"/>
<Button Height="80" FontSize="32" Background="LightBlue" Content="Click if TextBox as Text"
Command="{Binding ButtonParameterCommand, Source={StaticResource ViewModel}}" CommandParameter="{Binding Text, ElementName=textBoxTest}"/>
</StackPanel>
</Grid>
</Window>
ButtonViewModel.cs
public ButtonViewModel()
{
ButtonCommand = new ButtonCommand();
ButtonParameterCommand = new ButtonParameterCommand();
}
public ICommand ButtonCommand { get; }
public ICommand ButtonParameterCommand { get; }
CommandBase.cs
abstract class CommandBase : ICommand
{
public event EventHandler CanExecuteChanged;
public virtual bool CanExecute(object parameter)
{
return true;
}
public abstract void Execute(object parameter);
protected void OnCanExecutedChanged()
{
CanExecuteChanged?.Invoke(this, new EventArgs());
}
}
ButtonCommand.cs
public override void Execute(object parameter)
{
MessageBox.Show("Button is Clicked");
}
ButtonParameterCommand.cs
public override bool CanExecute(object parameter)
{
return true;
}
public override void Execute(object parameter)
{
MessageBox.Show(parameter as string);
}
我的问题是,如果 IsNullOrEmpty 上方的文本框,我想禁用第二个按钮,但是我认为可以解决此问题的代码会使该按钮永久禁用。我一直在尝试的代码是`
public override bool CanExecute(object parameter)
{
if (parameter != null)
{
if (String.IsNullOrEmpty(parameter as string))
{
return false;
}
else
{
return true;
}
}
return false;
}
这是我的错误还是Xaml绑定?我希望有人能提供帮助,并在此先感谢您的帮助。`
每当 TextBox
中的文本更改时,您需要引发命令的 CanExecuteChanged
事件。
创建 CommandBase
class public
的 OnCanExecutedChanged()
方法,并从您使用的来源 属性 的 setter 调用它将 TextBox
绑定到:
public class ButtonViewModel
{
public ButtonViewModel()
{
ButtonCommand = new ButtonCommand();
ButtonParameterCommand = new ButtonParameterCommand();
}
private string _text;
public string Text
{
get { return _text; }
set
{
_text = value;
ButtonParameterCommand.OnCanExecutedChanged();
}
}
public ICommand ButtonCommand { get; }
public CommandBase ButtonParameterCommand { get; }
}
XAML:
<TextBox x:Name="textBoxTest" Margin="5" FontSize="36"
Text="{Binding Text, Source={StaticResource ViewModel}}"/>
但是你真的应该研究如何实现接受 Action<object>
和 Predicate<object>
的“中继”或“委托”命令,并在 [=20] 的实现中调用它们=] 和 CanExecute
方法。
我将继续探索 WPF 并尝试使用命令来遵循 MVVM。 我的简单代码如下。
MainWindow.xaml
<Window x:Class="ClickCommand.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:ClickCommand"
xmlns:vm="clr-namespace:ClickCommand.ViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<vm:ButtonViewModel x:Key="ViewModel"/>
</Window.Resources>
<Grid>
<StackPanel Width="350" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Vertical">
<Button Height="80" FontSize="32" Background="LightBlue" Content="Click Me"
Command="{Binding ButtonCommand, Source={StaticResource ViewModel}}"/>
<TextBox x:Name="textBoxTest" Margin="5" FontSize="36"/>
<Button Height="80" FontSize="32" Background="LightBlue" Content="Click if TextBox as Text"
Command="{Binding ButtonParameterCommand, Source={StaticResource ViewModel}}" CommandParameter="{Binding Text, ElementName=textBoxTest}"/>
</StackPanel>
</Grid>
</Window>
ButtonViewModel.cs
public ButtonViewModel()
{
ButtonCommand = new ButtonCommand();
ButtonParameterCommand = new ButtonParameterCommand();
}
public ICommand ButtonCommand { get; }
public ICommand ButtonParameterCommand { get; }
CommandBase.cs
abstract class CommandBase : ICommand
{
public event EventHandler CanExecuteChanged;
public virtual bool CanExecute(object parameter)
{
return true;
}
public abstract void Execute(object parameter);
protected void OnCanExecutedChanged()
{
CanExecuteChanged?.Invoke(this, new EventArgs());
}
}
ButtonCommand.cs
public override void Execute(object parameter)
{
MessageBox.Show("Button is Clicked");
}
ButtonParameterCommand.cs
public override bool CanExecute(object parameter)
{
return true;
}
public override void Execute(object parameter)
{
MessageBox.Show(parameter as string);
}
我的问题是,如果 IsNullOrEmpty 上方的文本框,我想禁用第二个按钮,但是我认为可以解决此问题的代码会使该按钮永久禁用。我一直在尝试的代码是`
public override bool CanExecute(object parameter)
{
if (parameter != null)
{
if (String.IsNullOrEmpty(parameter as string))
{
return false;
}
else
{
return true;
}
}
return false;
}
这是我的错误还是Xaml绑定?我希望有人能提供帮助,并在此先感谢您的帮助。`
每当 TextBox
中的文本更改时,您需要引发命令的 CanExecuteChanged
事件。
创建 CommandBase
class public
的 OnCanExecutedChanged()
方法,并从您使用的来源 属性 的 setter 调用它将 TextBox
绑定到:
public class ButtonViewModel
{
public ButtonViewModel()
{
ButtonCommand = new ButtonCommand();
ButtonParameterCommand = new ButtonParameterCommand();
}
private string _text;
public string Text
{
get { return _text; }
set
{
_text = value;
ButtonParameterCommand.OnCanExecutedChanged();
}
}
public ICommand ButtonCommand { get; }
public CommandBase ButtonParameterCommand { get; }
}
XAML:
<TextBox x:Name="textBoxTest" Margin="5" FontSize="36"
Text="{Binding Text, Source={StaticResource ViewModel}}"/>
但是你真的应该研究如何实现接受 Action<object>
和 Predicate<object>
的“中继”或“委托”命令,并在 [=20] 的实现中调用它们=] 和 CanExecute
方法。