如何使WPF内容根据一些绑定的数据条件化?

3
我希望创建一个菜单项,但显示的文本取决于视图模型的属性。 如果属性IsPlaying为true,则菜单项文本应为“暂停”,否则应为“播放”。
没有这个条件,菜单项应该是这样的:
<MenuItem Header="_Play" Command="{Binding Path=PlayCommand}" />

但是,“播放”和“暂停”应该互换(如果可能的话,PlayCommand也应该与PauseCommand互换,但这可以通过在PlayCommand中同时具有PlayCommand和PauseCommand的逻辑来解决)

4个回答

3
最简单的方法是首先将Header绑定到您的视图模型中返回基于IsPlaying值的Play或Pause的string Caption属性,并实现INotifyPropertyChanged。之后,当IsPlaying更改时,只需为Caption抛出更改通知即可。
虽然您可以使用转换器,但在这种情况下,这将是一种过度设计。

我最初投票支持转换器答案,但最终我认为我会选择这个。虽然它不太“漂亮”,但考虑到这里问题的相对简单性,这个解决方案可能是最简单和最快速的。 - David

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 属性上使用相同的绑定语法即可。我还从转换器中返回文本字符串,这并不是最佳实践(个人而言,我喜欢从字符串资源文件中检索值以使我的应用程序具有文化意识),但你可以理解这个思路。

1
另一种将字符串嵌入转换器的替代方法(这确实是“不太理想”的笑容)是在转换器上定义TrueText和FalseText属性,然后可以在XAML转换器资源中指定。这可以与资源检索(TrueResourceKey和FalseResourceKey)结合使用,以保持转换器代码可重用而不影响本地化。 - itowlson

1
有几种方法可以实现这个:
  1. 使用触发器。在 IsPlaying = True 上设置一个触发器,并将 Header 和 Command 设置为 Pause 和 PauseCommand。
  2. 有两个菜单项,播放和暂停,并使用一对触发器根据 IsPlaying 设置它们的可见性。(您也可以数据绑定可见性,但使用触发器可以避免定义 BooleanToInvisibilityConverter 的需要。)

对于选项1,给个赞;当然两种方法都可以,转换器也可以,但触发器更加干净,同时解决了命令问题。 - kiwipom

1
在WPF中,您可以使用DataTrigger根据视图模型中的状态更改内容(甚至可以使用此技术交换模板)。另一种选择是使用VisualStateManager(datatriggers的远房表亲,为了弥补Silverlight缺失而创建,然后也被移植到WPF)从一个状态(IsPlaying)转换到下一个(!IsPlaying),实现类似的更改。
我很想给出更详细的例子,但现在已经过了我的睡觉时间。也许今天晚些时候再说吧。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接