如何反转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); } }
接下来,在T
是Visibility
子类中:
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); } }
它工作得很好!
我错过了什么吗?