如何反转BooleanToVisibilityConverter?

我在WPF中使用BooleanToVisibilityConverter将控件的Visibility属性绑定到Boolean 。 这工作正常,但我想要一个控件隐藏,如果布尔是true ,并显示它是false

实现你自己的IValueConverter的实现。 示例实现在

http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

在你的Convert方法中,让它返回你想要的值而不是默认值。

您可以通过使用通用的IValueConverter实现来实现相同的目标,该实现可以将布尔值转换为可configuration的目标值(true和false)。 下面是一个这样的实现:

 public class BooleanConverter<T> : IValueConverter { public BooleanConverter(T trueValue, T falseValue) { True = trueValue; False = falseValue; } public T True { get; set; } public T False { get; set; } public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value is bool && ((bool) value) ? True : False; } public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return value is T && EqualityComparer<T>.Default.Equals((T) value, True); } } 

接下来,在TVisibility子类中:

 public sealed class BooleanToVisibilityConverter : BooleanConverter<Visibility> { public BooleanToVisibilityConverter() : base(Visibility.Visible, Visibility.Collapsed) {} } 

最后,这是如何在XAML中使用BooleanToVisibilityConverter ,并将其configuration为,例如,使用Collapsed for true和Visible for false:

 <Application.Resources> <app:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" True="Collapsed" False="Visible" /> </Application.Resources> 

当你想绑定一个名为IsHidden的布尔属性而不是IsVisible时,这个反转是很有用的。

 using System; using System.Globalization; using System.Windows; using System.Windows.Data; public sealed class BooleanToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var flag = false; if (value is bool) { flag = (bool)value; } else if (value is bool?) { var nullable = (bool?)value; flag = nullable.GetValueOrDefault(); } if (parameter != null) { if (bool.Parse((string)parameter)) { flag = !flag; } } if (flag) { return Visibility.Visible; } else { return Visibility.Collapsed; } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { var back = ((value is Visibility) && (((Visibility)value) == Visibility.Visible)); if (parameter != null) { if ((bool)parameter) { back = !back; } } return back; } } 

然后传递一个true或false作为ConverterParameter

  <Grid.Visibility> <Binding Path="IsYesNoButtonSetVisible" Converter="{StaticResource booleanToVisibilityConverter}" ConverterParameter="true"/> </Grid.Visibility> 

写自己的是现在最好的解决scheme。 这里是一个转换器的例子,可以同时做正常和反转。 如果你有任何问题,只要问。

 [ValueConversion(typeof(bool), typeof(Visibility))] public class InvertableBooleanToVisibilityConverter : IValueConverter { enum Parameters { Normal, Inverted } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var boolValue = (bool)value; var direction = (Parameters)Enum.Parse(typeof(Parameters), (string)parameter); if(direction == Parameters.Inverted) return !boolValue? Visibility.Visible : Visibility.Collapsed; return boolValue? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return null; } } 
 <UserControl.Resources> <Converters:InvertableBooleanToVisibilityConverter x:Key="_Converter"/> </UserControl.Resources> <Button Visibility="{Binding IsRunning, Converter={StaticResource _Converter}, ConverterParameter=Inverted}">Start</Button> 

还有Codeplex上的WPF转换器项目。 在他们的文档中,他们说你可以使用他们的MapConverter从可见性枚举转换为布尔

 <Label> <Label.Visible> <Binding Path="IsVisible"> <Binding.Converter> <con:MapConverter> <con:Mapping From="True" To="{x:Static Visibility.Visible}"/> <con:Mapping From="False" To="{x:Static Visibility.Hidden}"/> </con:MapConverter> </Binding.Converter> </Binding> </Label.Visible> </Label> 

使用xaml Control Visibility Property绑定ViewModel布尔值(IsButtonVisible)的另一种方法。 没有编码,没有转换,只是造型。

 <Style TargetType={x:Type Button} x:Key="HideShow"> <Style.Triggers> <DataTrigger Binding="{Binding IsButtonVisible}" Value="False"> <Setter Property="Visibility" Value="Hidden"/> </DataTrigger> </Style.Triggers> </Style> <Button Style="{StaticResource HideShow}">Hello</Button> 

或者真正的懒惰的方式,只是利用已有的东西,并翻转它:

 public class InverseBooleanToVisibilityConverter : IValueConverter { private BooleanToVisibilityConverter _converter = new BooleanToVisibilityConverter(); public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { var result = _converter.Convert(value, targetType, parameter, culture) as Visibility?; return result == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { var result = _converter.ConvertBack(value, targetType, parameter, culture) as bool?; return result == true ? false : true; } } 

我只是做了一个这个post。 我使用了和Michael Hohlios一样的想法。 只有,我用属性,而不是使用“对象参数”。

将可见性绑定到WPF中的bool值

在我看来,使用属性使得它更具可读性。

 <local:BoolToVisibleOrHidden x:Key="BoolToVisConverter" Collapse="True" Reverse="True" /> 

这是我写的一个,用了很多。 它使用布尔转换器参数来指示是否反转该值,然后使用XOR执行否定操作:

 [ValueConversion(typeof(bool), typeof(System.Windows.Visibility))] public class BooleanVisibilityConverter : IValueConverter { System.Windows.Visibility _visibilityWhenFalse = System.Windows.Visibility.Collapsed; /// <summary> /// Gets or sets the <see cref="System.Windows.Visibility"/> value to use when the value is false. Defaults to collapsed. /// </summary> public System.Windows.Visibility VisibilityWhenFalse { get { return _visibilityWhenFalse; } set { _visibilityWhenFalse = value; } } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { bool negateValue; Boolean.TryParse(parameter as string, out negateValue); bool val = negateValue ^ System.Convert.ToBoolean(value); //Negate the value when negateValue is true using XOR return val ? System.Windows.Visibility.Visible : _visibilityWhenFalse; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { bool negateValue; Boolean.TryParse(parameter as string, out negateValue); if ((System.Windows.Visibility)value == System.Windows.Visibility.Visible) return true ^ negateValue; else return false ^ negateValue; } } 

这是一个XOR真值表供参考:

  XOR xy XOR --------- 0 0 0 0 1 1 1 0 1 1 1 0 

如果你不喜欢写自定义转换器,你可以使用数据触发器来解决这个问题:

 <Style.Triggers> <DataTrigger Binding="{Binding YourBinaryOption}" Value="True"> <Setter Property="Visibility" Value="Visible" /> </DataTrigger> <DataTrigger Binding="{Binding YourBinaryOption}" Value="False"> <Setter Property="Visibility" Value="Collapsed" /> </DataTrigger> </Style.Triggers> 

写你自己的转换。

 public class ReverseBooleanToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // your converter code here } } 

我正在寻找一个更一般的答案,但找不到它。 我写了一个可以帮助别人的转换器。

这是基于我们需要区分六种不同情况的事实:

  • 真2可见,假2隐藏
  • 真2可见,假2倒塌
  • 真2隐藏,假2可见
  • 真2折叠,假2可见
  • 真2隐藏,假2倒塌
  • 真2折叠,假2隐藏

这是我的前4个例子的执行情况:

 [ValueConversion(typeof(bool), typeof(Visibility))] public class BooleanToVisibilityConverter : IValueConverter { enum Types { /// <summary> /// True to Visible, False to Collapsed /// </summary> t2v_f2c, /// <summary> /// True to Visible, False to Hidden /// </summary> t2v_f2h, /// <summary> /// True to Collapsed, False to Visible /// </summary> t2c_f2v, /// <summary> /// True to Hidden, False to Visible /// </summary> t2h_f2v, } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var b = (bool)value; string p = (string)parameter; var type = (Types)Enum.Parse(typeof(Types), (string)parameter); switch (type) { case Types.t2v_f2c: return b ? Visibility.Visible : Visibility.Collapsed; case Types.t2v_f2h: return b ? Visibility.Visible : Visibility.Hidden; case Types.t2c_f2v: return b ? Visibility.Collapsed : Visibility.Visible; case Types.t2h_f2v: return b ? Visibility.Hidden : Visibility.Visible; } throw new NotImplementedException(); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { var v = (Visibility)value; string p = (string)parameter; var type = (Types)Enum.Parse(typeof(Types), (string)parameter); switch (type) { case Types.t2v_f2c: if (v == Visibility.Visible) return true; else if (v == Visibility.Collapsed) return false; break; case Types.t2v_f2h: if (v == Visibility.Visible) return true; else if (v == Visibility.Hidden) return false; break; case Types.t2c_f2v: if (v == Visibility.Visible) return false; else if (v == Visibility.Collapsed) return true; break; case Types.t2h_f2v: if (v == Visibility.Visible) return false; else if (v == Visibility.Hidden) return true; break; } throw new InvalidOperationException(); } } 

例:

 Visibility="{Binding HasItems, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter='t2v_f2c'}" 

我认为参数很容易记住。

希望它有助于某人。

您可以使用QuickConverter

使用QuickConverter,您可以使用BindingExpression内联编写转换器逻辑

这是一个倒转的BooleanToVisibility转换器:

 Visibility="{qc:Binding '!$P ? Visibility.Visible : Visibility.Collapsed', P={Binding Example}}" 

您可以通过NuGet添加QuickConverter。 看看安装文件。 链接: https : //quickconverter.codeplex.com/

一个简单的单向版本可以这样使用:

 Visibility="{Binding IsHidden, Converter={x:Static Ui:Converters.BooleanToVisibility}, ConverterParameter=true} 

可以这样实现:

 public class BooleanToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var invert = false; if (parameter != null) { invert = Boolean.Parse(parameter.ToString()); } var booleanValue = (bool) value; return ((booleanValue && !invert) || (!booleanValue && invert)) ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } 

我知道这是过时的,但是,你不需要重新执行任何事情。

我所做的就是否定这样的财产价值:

 <!-- XAML code --> <StackPanel Name="x" Visibility="{Binding Path=Specials, ElementName=MyWindow, Converter={StaticResource BooleanToVisibilityConverter}}"></StackPanel> <StackPanel Name="y" Visibility="{Binding Path=NotSpecials, ElementName=MyWindow, Converter={StaticResource BooleanToVisibilityConverter}}"></StackPanel> 

….

 //Code behind public bool Specials { get { return (bool) GetValue(SpecialsProperty); } set { NotSpecials= !value; SetValue(SpecialsProperty, value); } } public bool NotSpecials { get { return (bool) GetValue(NotSpecialsProperty); } set { SetValue(NotSpecialsProperty, value); } } 

它工作得很好!

我错过了什么吗?