我想创建一个菜单项,但显示的文本取决于视图模型的属性。
如果属性IsPlaying
为true,则MenuItem文本应为“Pause”,否则应为“Play”。
如果没有这个条件,MenuItem应该是这样的:
<MenuItem Header="_Play" Command="{Binding Path=PlayCommand}" />
但是,“Play”和“Pause”应该交换(如果可能,PlayCommand也应该与PauseCommand交换,但这可以通过在PlayCommand中同时使用PlayCommand和PauseCommand的逻辑来实现)
答案 0 :(得分:3)
最简单的方法是首先将Header
绑定到viewmodel中的string Caption
属性,该属性根据IsPlaying
的值返回Play或Pause并实现{{ 1}}。在此之后,只有在INotifyPropertyChanged
发生更改时,才会发送Caption
的更改通知。
虽然你可以使用转换器,但在这种情况下它将是一种过度杀伤。
答案 1 :(得分:1)
对此最好的是转换器。您的代码将如下所示:
<UserControl xmlns:myConverters="MyRandomNamespace">
<UserControl.Resources>
<myConverters:MyMenuTextConverter x:Key="MyMenuTextConverter" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<TextBlock Text="{Binding IsPlaying, Converter={StaticResource MyMenuTextConverter }}" />
</Grid>
</UserControl>
并在转换器中:
namespace MyRandomNamespace
{
public class MyMenuTextConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((bool) value == true)
return "Pause";
return "Play";
}
}
}
我使用TextBlock
来显示绑定背后的概念,您所要做的就是在MenuItem的相应属性上使用相同的绑定语法。我也从转换器返回文字文本,这不是最佳的(我个人喜欢我的文本转换器从字符串资源文件中检索它们的值,以便我的应用程序具有文化意识),但你明白了。
答案 2 :(得分:1)
有两种方法可以做到这一点:
答案 3 :(得分:1)
在WPF中,您可以使用DataTrigger根据视图模型中的状态更改内容(您甚至可以使用此技术来交换模板)。另一个替代方法是使用VisualStateManager(为Silverlight不存在而创建的数据触发器的远程表亲,然后向后移植到WPF)来执行从一个状态(IsPlaying)到下一个状态(!IsPlaying)的类似更改。
我想提供一个更详细的例子,但它已经过了我的睡觉时间。也许今天晚些时候。