您好 stackoverflow 社区, 我是 MVVM 主题的新手,但能够了解一些基础知识。我编写了一些教程并实现了自己的 RealyCommand 和 ViewModelBase。
我的按钮可以与命令绑定一起使用,并且使用 CanExecute 启用/禁用也可以正常工作。
MVVM 工具包: 在实现了用于消息传递的 MVVM Toolkit 后,我在 MS 页面上查看了更多示例,发现该工具包以更少的代码提供了 RelayCommand 和更多功能,因此我想用 MVVM Toolkit 的代码替换我自己的 MVVM 代码。
在它的生命周期中,我无法弄清楚为什么 canExecute 不起作用,它将 bool 变量从 true 更新为 false,反之亦然,但按钮不会启用/禁用。 我错过了什么?
测试视图模型:
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace WorkOrderApplication.ViewModels
{
public partial class TestViewModel : ObservableObject
{
public TestViewModel()
{
Testbutton1 = true;
Testbutton2 = true;
}
[ObservableProperty]
private bool _testbutton1;
[ObservableProperty]
private bool _testbutton2;
[RelayCommand(CanExecute = nameof(CanExecuteButton1))]
private void ClickButton1()
{
Testbutton1 = false;
Testbutton2 = true;
}
private bool CanExecuteButton1()
{
return Testbutton1;
}
[RelayCommand(CanExecute = nameof(CanExecuteButton2))]
public void ClickButton2()
{
Testbutton1 = true;
Testbutton2 = false;
}
private bool CanExecuteButton2()
{
return Testbutton2;
}
}
}
测试视图:
<UserControl x:Class="WorkOrderApplication.Views.TestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:designer="clr-namespace:WorkOrderApplication.ViewModels.Designer"
xmlns:customcontrol="clr-namespace:WorkOrderApplication.Views.Controls"
xmlns:viewmodels="clr-namespace:WorkOrderApplication.ViewModels"
mc:Ignorable="d"
d:DesignWidth="1920"
d:DesignHeight="1080">
<UserControl.Resources>
<Style TargetType="Button" x:Key="RoundButton">
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="10" />
</Style>
</Style.Resources>
<Setter Property="FontSize" Value="30"/>
<Setter Property="Foreground" Value="white"/>
<Setter Property="Background" Value="green"/>
<Setter Property="Width" Value="130"/>
<Setter Property="Height" Value="50"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="940"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="0,0,0,0" Background="White">
<DockPanel Margin="0,0,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="135"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="166"/>
<ColumnDefinition Width="166"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Content="Button 1" Grid.Column="0"
Style="{DynamicResource RoundButton}"
Command="{Binding ClickButton1Command}">
</Button>
<Button Content="Button 2" Grid.Column="1"
Style="{DynamicResource RoundButton}"
Command="{Binding ClickButton2Command}">
</Button>
</Grid>
</DockPanel>
</Grid>
<Grid Grid.Row="1" Margin="0,0,0,0" Background="White">
<Label Content="Content:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontSize="60" Height="100" Width="300"/>
</Grid>
</Grid>
根据docs,您必须设置
NotifyCanExecuteChangedFor
属性
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace WorkOrderApplication.ViewModels
{
public partial class TestViewModel : ObservableObject
{
public TestViewModel()
{
Testbutton1 = true;
Testbutton2 = true;
}
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(ClickButton1))]
private bool _testbutton1;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(ClickButton2))]
private bool _testbutton2;
[RelayCommand(CanExecute = nameof(CanExecuteButton1))]
private void ClickButton1()
{
Testbutton1 = false;
Testbutton2 = true;
}
private bool CanExecuteButton1()
{
return Testbutton1;
}
[RelayCommand(CanExecute = nameof(CanExecuteButton2))]
public void ClickButton2()
{
Testbutton1 = true;
Testbutton2 = false;
}
private bool CanExecuteButton2()
{
return Testbutton2;
}
}
}