通知用户命令无法执行

本文关键字:执行 命令 用户 通知 | 更新日期: 2023-09-27 18:11:47

我有一个文本框,绑定到这样的命令:

<TextBox Text="{Binding Path=TextContent, UpdateSourceTrigger=PropertyChanged}">
        <TextBox.InputBindings>
            <KeyBinding Command="{Binding Path=MyCommand}" Key="Enter" />
        </TextBox.InputBindings>
</TextBox>

属性TextContent是在ViewModel中定义的字符串。命令MyCommand也在ViewModel中定义。ViewModel不知道View。

当文本框有焦点并且按回车键时,该命令将被调用。不幸的是,如果CanExecute返回false,用户无法(直观地)看到命令没有执行,因为TextBox中没有视觉变化。

我正在寻找关于如何向用户显示命令在他按下enter后无法执行的建议。

我的想法(和我对它们的怀疑):

  • CanExecute返回false时禁用文本框:这是没有选项,因为CanExecute的返回值可以在每次键入/更改字母时更改(文本框中的文本影响CanExecute的结果)。当它第一次被禁用时,用户不能再输入,因此它将永远处于禁用状态

  • 显示命令未执行的消息框:记住,ViewModel不知道View。甚至可以从ViewModel打开消息框吗?此外,我应该把打开消息框的调用放在哪里?不是在CanExecute内,因为我只想在点击enter后获得消息框,而不是每次CanExecute返回false。也许让CanExecute总是返回true,并在Execute内做检查:如果检查是好的,做命令的东西,如果不是,向用户显示一些消息。但是,拥有CanExecute的意义完全被忽略了…

我想保持MVVM,但一些代码后重定向的东西到ViewModel似乎对我来说是好的。

通知用户命令无法执行

我建议如下解决方案:

这是一个关于如何通知用户的例子,我现在正在研究。

我想让用户输入一个int、double或string类型的数据限制。它要检查用户输入的类型是否正确。我使用属性ValidateLimits检查字符串MyLimits,在您的情况下是TextContent

每次用户在TextBox中键入任何内容时,ValidateLimits将检查字符串。如果它不是文本框中的有效字符串,则返回false,否则返回true。如果为false,则通过在文本框上设置一些属性来突出显示它,在我的情况下是一些边框和前景颜色,也是一个工具提示。

同样在你的情况下,你想在CanExecute方法中调用你的Validate方法。

如果你已经有了一个检查命令是否正确的函数,那么就把它添加到DataTrigger绑定中。

<TextBox Text="{Binding MyLimit1, UpdateSourceTrigger=PropertyChanged}" Margin="-6,0,-6,0">
  <TextBox.Style>
    <Style TargetType="TextBox">
     <!-- Properties that needs to be changed with the data trigger cannot be set outside the style. Default values needs to be set inside the style -->
     <Setter Property="ToolTip" Value="{Binding FriendlyCompareRule}"/>
       <Style.Triggers>
         <DataTrigger Binding="{Binding ValidateLimits}" Value="false">
           <Setter Property="Foreground" Value="Red"/>
           <Setter Property="BorderBrush" Value="Red"/>
           <Setter Property="BorderThickness" Value="2"/>
           <Setter Property="ToolTip" Value="Cannot parse value to correct data type"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </TextBox.Style>

public bool ValidateLimits
{
  get
  {
    // Check if MyLimit1 is correct data type
    return true/false;
  }
}

Command类中使用属性bool IsCommandExecuted。设置此属性。

使用ToolTip并将其IsOpen属性绑定到IsCommandExecuted属性,如下所示:

<TextBox ...>
    <TextBox.ToolTip>
        <ToolTip IsOpen="{Binding MyCommand.IsCommandExecuted}">...</ToolTip>
    </TextBox.ToolTip>
</TextBox>

这解释了概念,请相应地修改