Using RelayCommand CanExecute with CommunityToolkit.MVVM and Microsoft.Xaml.Behaviors.Wpf

huangapple go评论130阅读模式
英文:

Using RelayCommand CanExecute with CommunityToolkit.MVVM and Microsoft.Xaml.Behaviors.Wpf

问题

我正在尝试将 CommunityToolkit.MVVM (8.2.0)Microsoft.Xaml.Behaviors.Wpf (1.1.39) 结合使用,并使用 RelayCommands CanExecute 功能来启用/禁用按钮。

在我的情况下,我需要查询 PreviewMouseDown 事件(而不是标准的点击事件),这可以通过 EventTrigger 很好地实现。不幸的是,使用 Behavior 时按钮的开/关状态在视觉上没有显示出来,但按钮的功能确实已正确启用/禁用。

我希望具有 EventTrigger 的按钮的行为与没有 EventTrigger 的按钮相同。我对 WPF 还很陌生,请原谅我 Using RelayCommand CanExecute with CommunityToolkit.MVVM and Microsoft.Xaml.Behaviors.Wpf

以下是 View.xaml(代码部分为空):

<Window x:Class="Example.View"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Example"
        mc:Ignorable="d"
        Title="View" SizeToContent="WidthAndHeight" ResizeMode="NoResize">
  <Window.DataContext>
    <local:ViewModel/>
  </Window.DataContext>
  <StackPanel Margin="5" Orientation="Horizontal">
    <Button Command="{Binding ToggleAllowenceCommand}" Content="Toggle Allowence"/>
    
    <StackPanel Margin="5,0,0,0">
      
      <Button Command="{Binding MouseDownCommand}">
        <TextBlock Text="Button without xaml.behaviors"/>
      </Button>
      
      <Button Margin="0,5,0,0">
        <i:Interaction.Triggers>
          <i:EventTrigger EventName="PreviewMouseDown">
            <i:InvokeCommandAction Command="{Binding MouseDownCommand}"/>
          </i:EventTrigger>
        </i:Interaction.Triggers>
        <TextBlock Text="Button with xaml.behaviors"/>
      </Button>
      
    </StackPanel>    
  </StackPanel>
</Window>

ViewModel.cs:

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace Example;

partial class ViewModel : ObservableObject
{
  public ViewModel() { }

  [ObservableProperty]
  [NotifyCanExecuteChangedFor(nameof(MouseDownCommand))]
  private bool _allowence = false;

  private bool CanExecuteMouseDown() => Allowence;

  [RelayCommand(CanExecute = nameof(CanExecuteMouseDown))]
  private void MouseDown() { }

  [RelayCommand]
  private void ToggleAllowence() => Allowence = !Allowence;
}

我尝试过向具有 EventTrigger 的按钮添加命令绑定,就像我在第一个按钮中所做的那样,但是某种方式看起来不对,或者我错了吗?后来,我想绑定更多的 EventTrigger,比如 PreviewMouseUp,所以似乎我不能避免将 Behaviors 与 MVVM 结合使用?

英文:

I am trying to combine the CommunityToolkit.MVVM (8.2.0) with Microsoft.Xaml.Behaviors.Wpf (1.1.39) and enable/disable a button using RelayCommands CanExecute functionality.

In my case I need to query the PreviewMouseDown event (Not a standard click event), this works quite well with an EventTrigger. Unfortunately, the on/off state is not visually displayed for the button with Behavior - but the functionality of the button is indeed properly enabled/disabled.

I want the button with EventTrigger to behave the same as the one without. I am quite new to WPF, please forgive me Using RelayCommand CanExecute with CommunityToolkit.MVVM and Microsoft.Xaml.Behaviors.Wpf

Here is the View.xaml (code behind is "empty"):

<Window x:Class="Example.View"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Example"
        mc:Ignorable="d"
        Title="View" SizeToContent="WidthAndHeight" ResizeMode="NoResize">
  <Window.DataContext>
    <local:ViewModel/>
  </Window.DataContext>
  <StackPanel Margin="5" Orientation="Horizontal">
    <Button Command="{Binding ToggleAllowenceCommand}" Content="Toggle Allowence"/>
    
    <StackPanel Margin="5,0,0,0">
      
      <Button Command="{Binding MouseDownCommand}">
        <TextBlock Text="Button without xaml.behaviors"/>
      </Button>
      
      <Button Margin="0,5,0,0">
        <i:Interaction.Triggers>
          <i:EventTrigger EventName="PreviewMouseDown">
            <i:InvokeCommandAction Command="{Binding MouseDownCommand}"/>
          </i:EventTrigger>
        </i:Interaction.Triggers>
        <TextBlock Text="Button with xaml.behaviors"/>
      </Button>
      
    </StackPanel>    
  </StackPanel>
</Window>

ViewModel.cs:

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace Example;

partial class ViewModel : ObservableObject
{
  public ViewModel() { }

  [ObservableProperty]
  [NotifyCanExecuteChangedFor(nameof(MouseDownCommand))]
  private bool _allowence = false;

  private bool CanExecuteMouseDown() => Allowence;

  [RelayCommand(CanExecute = nameof(CanExecuteMouseDown))]
  private void MouseDown() { }

  [RelayCommand]
  private void ToggleAllowence() => Allowence = !Allowence;
}

I experimented with adding a command binding to the button with the EventTrigger like I did with the first button - but somehow it looks wrong, or am I wrong? Later I wanted to bind more EventTriggers - like PreviewMouseUp, so it seems I can't avoid Behaviors in combination with MVVM?

答案1

得分: 2

很不幸,按钮的开/关状态在 Behavior 中没有进行视觉显示,但确实已正确启用/禁用按钮的功能。

这是预期的行为。如此博客文章所述," InvokeCommandAction 不会根据命令的 CanExecute 方法自动启用或禁用控件,不像具有 Command 属性并可以直接绑定到命令的控件。"

英文:

>Unfortunately, the on/off state is not visually displayed for the button with Behavior - but the functionality of the button is indeed properly enabled/disabled.

This is the expected behaviour. As stated in this blog post, "an InvokeCommandAction doesn't automatically enable or disable the control based on the command's CanExecute method, unlike controls that have a Command property and can be bound directly to a command."

huangapple
  • 本文由 发表于 2023年6月8日 20:48:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76432016.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定