通知用户命令无法执行
Notify user that command could not be executed
我有一个文本框绑定到这样的命令:
<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。
只要 TextBox 获得焦点并按下回车键,就会调用该命令。不幸的是,如果 CanExecute
returns 为 false,则用户无法(视觉上)看到命令未执行,因为 TextBox 中没有视觉变化。
我正在寻找有关如何向用户显示在他按下 enter 后命令无法执行的建议。
我的想法(以及我对它们的怀疑):
当 CanExecute
returns false
时禁用文本框:这不是选项,因为 CanExecute
的 return 值可以每次字母为 typed/changed 时都会更改(TextBox 中的文本会影响 CanExecute
的结果)。第一次禁用时,用户无法再输入,因此它将永远禁用。
显示命令未执行的消息框:记住,ViewModel 不知道 View。 甚至可以从 ViewModel 打开消息框吗? 此外,我应该在哪里调用打开消息框?不在 CanExecute
内,因为我只想在按下回车后得到消息框,而不是每次 CanExecute
returns false
。也许让 CanExecute
总是 return true
并在 Execute
中进行检查:如果检查没问题,执行命令,如果没有,向用户显示一些消息。但是,CanExecute
的意义完全被忽略了......
我想保留 MVVM,但一些用于将内容重定向到 ViewModel 的代码隐藏对我来说似乎没问题。
我建议采用以下解决方案。
这是一个关于如何通知用户我正在处理的示例。
我希望用户输入一个类型为 int、double 或 string 的数据限制。
它想要检查以便用户输入正确的类型。
我使用 属性 ValidateLimits 检查字符串 MyLimits 在你的情况下是 TextContent .
每次用户在文本框中键入任何内容时,ValidateLimits 都会检查该字符串。如果它不是文本框中的有效字符串,则 return false 否则 return true。
如果为 false,则通过在 TextBox 上设置一些属性来使用 DataTrigger 突出显示它,在我的例子中是一些边框和前景色,还有一个工具提示。
此外,在您的情况下,您想在 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
class 中使用 属性 bool IsCommandExecuted
。相应地设置此 属性。
使用 ToolTip
并将其 IsOpen
属性 绑定到 IsCommandExecuted
属性,如下所示:
<TextBox ...>
<TextBox.ToolTip>
<ToolTip IsOpen="{Binding MyCommand.IsCommandExecuted}">...</ToolTip>
</TextBox.ToolTip>
</TextBox>
这里解释了概念,相应地修改它。
我有一个文本框绑定到这样的命令:
<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。
只要 TextBox 获得焦点并按下回车键,就会调用该命令。不幸的是,如果 CanExecute
returns 为 false,则用户无法(视觉上)看到命令未执行,因为 TextBox 中没有视觉变化。
我正在寻找有关如何向用户显示在他按下 enter 后命令无法执行的建议。
我的想法(以及我对它们的怀疑):
当
CanExecute
returnsfalse
时禁用文本框:这不是选项,因为CanExecute
的 return 值可以每次字母为 typed/changed 时都会更改(TextBox 中的文本会影响CanExecute
的结果)。第一次禁用时,用户无法再输入,因此它将永远禁用。显示命令未执行的消息框:记住,ViewModel 不知道 View。 甚至可以从 ViewModel 打开消息框吗? 此外,我应该在哪里调用打开消息框?不在
CanExecute
内,因为我只想在按下回车后得到消息框,而不是每次CanExecute
returnsfalse
。也许让CanExecute
总是 returntrue
并在Execute
中进行检查:如果检查没问题,执行命令,如果没有,向用户显示一些消息。但是,CanExecute
的意义完全被忽略了......
我想保留 MVVM,但一些用于将内容重定向到 ViewModel 的代码隐藏对我来说似乎没问题。
我建议采用以下解决方案。
这是一个关于如何通知用户我正在处理的示例。
我希望用户输入一个类型为 int、double 或 string 的数据限制。 它想要检查以便用户输入正确的类型。 我使用 属性 ValidateLimits 检查字符串 MyLimits 在你的情况下是 TextContent .
每次用户在文本框中键入任何内容时,ValidateLimits 都会检查该字符串。如果它不是文本框中的有效字符串,则 return false 否则 return true。 如果为 false,则通过在 TextBox 上设置一些属性来使用 DataTrigger 突出显示它,在我的例子中是一些边框和前景色,还有一个工具提示。
此外,在您的情况下,您想在 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
class 中使用 属性 bool IsCommandExecuted
。相应地设置此 属性。
使用 ToolTip
并将其 IsOpen
属性 绑定到 IsCommandExecuted
属性,如下所示:
<TextBox ...>
<TextBox.ToolTip>
<ToolTip IsOpen="{Binding MyCommand.IsCommandExecuted}">...</ToolTip>
</TextBox.ToolTip>
</TextBox>
这里解释了概念,相应地修改它。