如何使WPF内容以某些绑定数据为条件?

时间:2011-02-16 06:29:40

标签: wpf data-binding mvvm menuitem

我想创建一个菜单项,但显示的文本取决于视图模型的属性。 如果属性IsPlaying为true,则MenuItem文本应为“Pause”,否则应为“Play”。

如果没有这个条件,MenuItem应该是这样的:

<MenuItem Header="_Play" Command="{Binding Path=PlayCommand}" />

但是,“Play”和“Pause”应该交换(如果可能,PlayCommand也应该与PauseCommand交换,但这可以通过在PlayCommand中同时使用PlayCommand和PauseCommand的逻辑来实现)

4 个答案:

答案 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)

有两种方法可以做到这一点:

  1. 使用触发器。在IsPlaying = True上设置触发器,并将Header和Command分别设置为Pause和PauseCommand。
  2. 有两个菜单项,播放和暂停,并使用一对触发器根据IsPlaying设置其可见性。 (您也可以对Visibility进行数据绑定,但使用触发器可以避免定义BooleanToInvisibilityConverter。)

答案 3 :(得分:1)

在WPF中,您可以使用DataTrigger根据视图模型中的状态更改内容(您甚至可以使用此技术来交换模板)。另一个替代方法是使用VisualStateManager(为Silverlight不存在而创建的数据触发器的远程表亲,然后向后移植到WPF)来执行从一个状态(IsPlaying)到下一个状态(!IsPlaying)的类似更改。

我想提供一个更详细的例子,但它已经过了我的睡觉时间。也许今天晚些时候。