【问题标题】:WPF Visiblity Binding to Boolean Expression with multiple VariablesWPF 可见性绑定到具有多个变量的布尔表达式
【发布时间】:2017-02-20 11:08:26
【问题描述】:

我有两个布尔值,我想根据它们的值显示 Image,如下所示:

   <Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>

<Image Visibility="{Binding (Boolean1 && Boolean2),Converter={StaticResource BooleanToVisibilityConverter}}" />

注意 Boolean1 和 Boolean2 表达式。

【问题讨论】:

  • 绑定路径不支持这种表达式,在视图模型public bool Boolean3 { get { return Boolean1 &amp;&amp; Boolean2; }}中创建一个get-only属性并绑定到Boolean3
  • 必须有一个 B̶e̶t̶t̶e̶r̶ 简单的方法来做类似内联的事情?
  • 你需要使用多重绑定和多重值vonverter codearsenal.net/2013/12/…
  • 根据我的回答,使用 IMultiValueConverter 或带有 MultiDataTrigger 的 Style。
  • @Slacker 实际上让你直接在视图中编码会破坏整个 MVVM 概念,外观和功能必须分开

标签: wpf xaml


【解决方案1】:

XAML 中没有定义&amp;&amp; 运算符,但您可以绑定到多个属性并使用IMultiValueConverter

<Image>
    <Image.Visibility>
        <MultiBinding Converter="{StaticResource YourMultiConverter}">
            <Binding Path="Boolean1" />
            <Binding Path="Boolean2" />
        </MultiBinding>
    </Image.Visibility>
</Image>

public class YourMultiValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool a = (bool)values[0];
        bool b = (bool)values[1];

        return a && b ? Visibility.Visible : Visibility.Collapsed;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

或者您可以使用带有条件的Image 样式:

<Image>
    <Image.Style>
        <Style TargetType="Image">
            <Setter Property="Visibility" Value="Collapsed" />
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Boolean1}" Value="True" />
                        <Condition Binding="{Binding Boolean2}" Value="True" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Visibility" Value="Visible" />
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Image.Style>
</Image>

【讨论】:

  • 抱歉愚蠢的问题如何定义({StaticResource YourMultiConverter})?
  • @Stacker 与您定义任何转换器的方式相同,将其创建为相关资源字典中的静态资源,请记住,如果您还没有定义命名空间,则需要定义命名空间
  • 中的
  • 您应该在 ConvertBack 中返回 null,因为:“数据绑定引擎不会捕获由用户提供的转换器抛出的异常。任何由 ConvertBack 方法抛出的异常或任何未捕获的异常由 ConvertBack 方法调用的方法引发的被视为运行时错误的方法。通过返回 null 来处理预期的问题。 source
【解决方案2】:

mm8 提供了正确的答案,但是会有一点改进

public class LogicalAndConverter : IMultiValueConverter
{
    public IValueConverter FinalConverter{get;set;}

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool rtn = values.All(v=>(bool)v);

        if(FinalConverter==null)    
            return rtn;
        else
            return FinalConverter.Convert(rtn,targetType,parameter,culture);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

这允许您使用不同的转换器而无需重写多转换器

<local:LogicalAndConverter x:Key="LogicalAndConverter ">
    <local:LogicalAndConverter.FinalConverter>
        <BooleanToVisibilityConverter />
    </local:LogicalAndConverter.FinalConverter>
</local:LogicalAndConverter>

【讨论】:

  • 这是一个被低估的答案。真正光滑的转换器管道。
  • 我喜欢这个答案,因为它很灵活!
【解决方案3】:

如果您不介意在您的项目中添加另一个包,DevExpress 的 MVVM 框架(可免费获得)有一个名为 DXBinding 的绑定标记扩展,允许您编写绑定函数/表达式。

<Image Visibility="{DXBinding 'Boolean1 and Boolean2', Converter={StaticResource BooleanToVisibilityConverter}}"/>

【讨论】:

    【解决方案4】:

    你可以使用多值转换器来解决这个问题

    XAML:

     <TextBlock Name="textBlockOutput" Grid.Row="4" Grid.Column="2">
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource MultiValueConverter}">
                    <Binding Path="TextOne" />
                    <Binding Path="TextTwo" />
                    <Binding Path="TextThree" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    
    
    
    
     public class MultiValueConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            string one = values[0] as string;
            string two = values[1] as string;
            string three = values[2] as string;
            if(!string.IsNullOrEmpty(one) && !string.IsNullOrEmpty(two) && !string.IsNullOrEmpty(three))
            {
                return one + two + three;
            }
            return null;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    【讨论】:

    • 虽然你的答案是正确的,但更好地解释为什么这个修复它会改进这个答案
    猜你喜欢
    • 2016-06-11
    • 2020-09-02
    • 2013-01-15
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    相关资源
    最近更新 更多