52

有没有办法使用现有的 WPF BooleanToVisibilityConverter 转换器,但将 False 值转换为 Hidden 而不是默认的 Collapsed,或者我应该自己编写?我在一个项目中,做这样简单的事情需要巨大的开销(共享的东西进入一个单独的解决方案,重建/签入/合并过程是一个过度生长的变异庞然大物),所以我更喜欢如果我可以只将参数传递给现有参数,而不是跳过刚才提到的箍。

4

7 回答 7

133

我找到了最简单和最好的解决方案:

[ValueConversion(typeof(bool), typeof(Visibility))]
public sealed class BoolToVisibilityConverter : IValueConverter
{
  public Visibility TrueValue { get; set; }
  public Visibility FalseValue { get; set; }

  public BoolToVisibilityConverter()
  {
    // set defaults
    TrueValue = Visibility.Visible;
    FalseValue = Visibility.Collapsed;
  }

  public object Convert(object value, Type targetType, 
      object parameter, CultureInfo culture)
  {
    if (!(value is bool))
      return null;
    return (bool)value ? TrueValue : FalseValue;    
  }

  public object ConvertBack(object value, Type targetType, 
      object parameter, CultureInfo culture)
  {
    if (Equals(value, TrueValue))
      return true;
    if (Equals(value, FalseValue))
      return false;
    return null;
  }
}

使用它时,只需在 XAML 中配置一个完全符合您需要的版本,如下所示:

<Blah.Resources>
  <local:BoolToVisibilityConverter
         x:Key="BoolToHiddenConverter"
         TrueValue="Visible" FalseValue="Hidden" />
</Blah.Resources>

然后在一个或多个绑定中使用它,如下所示:

<Foo Visibility="{Binding IsItFridayAlready, 
                          Converter={StaticResource BoolToHiddenConverter}}" />

这个简单的解决方案解决了隐藏/折叠的偏好以及反转/否定效果。

SILVERLIGHT 用户必须删除该[ValueConversion]声明,因为该属性不是 Silverlight 框架的一部分。它在 WPF 中也不是严格需要的,但与内置转换器一致。

于 2010-06-27T19:03:42.917 回答
31

不幸的是,它只能转换为可见或折叠,因此您必须自己编写。这是根据反射器的转换方法:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    bool flag = false;
    if (value is bool)
    {
        flag = (bool)value;
    }
    else if (value is bool?)
    {
        bool? nullable = (bool?)value;
        flag = nullable.HasValue ? nullable.Value : false;
    }
    return (flag ? Visibility.Visible : Visibility.Collapsed);
}
于 2010-06-27T16:48:10.583 回答
4

我喜欢使用参数来反转可见性逻辑:要反转逻辑,只需简单地说:ConverterParameter=Reverse in your xaml code

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    bool flag = false;
    if (value is bool)
    {
        flag = (bool)value;
    }

    var reverse = parameter as string;
    if(reverse != null && reverse == "Reverse")
        flag != flag;

    return (flag ? Visibility.Visible : Visibility.Collapsed);
}
于 2010-06-27T17:12:28.710 回答
4

你不能只使用样式而不是转换器吗?代码将类似于:

<Style x:Key="Triggers" TargetType="Button">
    <Style.Triggers>
    <Trigger Property="{Binding ...}" Value="false">
        <Setter Property = "Visibility" Value="Hidden"/>
    </Trigger>
    </Style.Triggers>
</Style>

您需要自己提供属性绑定以指向您的 bool 属性。

于 2010-06-27T16:48:58.850 回答
1

我写了 BoolToVisibilityConverte 你可以在参数中传递不可见状态:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    var boolValue = (bool) value;
    return boolValue ? Visibility.Visible : (parameter ?? Visibility.Hidden);
}

所以你可以像这样绑定:

Visibility="{Binding SomeBool, Converter={StaticResource ResourceKey=BooleanToVisibilityConverter}, ConverterParameter={x:Static Visibility.Collapsed}}"

希望这可以帮助 :)

于 2016-08-03T12:35:22.630 回答
0

使用 Caliburn.Micro,我有以下代码适用于我的简单用例,也可能适用于其他人。

在我的视图中,我有一个想要隐藏的按钮,除非我的变量之一具有正长度字符串:

<Button x:Name="SelectBinaryFilePath" Content="Select" Visibility="{Binding CanSelectBinaryFile}" />

在我的 ViewModel 中,我具有以下属性:

public Visibility CanSelectBinaryFile
{
    get
    {
        return String.IsNullOrEmpty(FileSystemPath) ? Visibility.Hidden : Visibility.Visible;
    }
}

确保执行NotifyOfPropertyChange以确保CanSelectBinaryFile更新道具。

于 2021-02-10T08:04:00.390 回答
0

我遇到了这个问题,我的解决方案可能是非常情境化的,但无论如何我都会分享它。由于我的情况,我能够在没有转换器的情况下使用简单的代码来模拟转换器。仅当绑定到文本框的变量使数字框(通过正则表达式确保其数字)不为 0 时,我才进行可见性更改。整个代码如下,但是 WPF 和 C# 的第一位是你真正需要的您将在代码中的其他地方更改您的布尔值。wpf:

    Visibility="{Binding Path=Visible}"

C#

    public class foo : INotifyPropertyChanged
    {
        private bool vis = false;
        public object Visible
        {
            get 
            { 
                if (vis == true) 
                { 
                    return Visibility.Visible; 
                } 
                else 
                { 
                    return Visibility.Hidden; 
                } 
            }
            set
            { 
                vis = (bool)value; 
                OnPropertyChanged(nameof(Visible)); 
            }
        }
        public int Value_b
        {
            get 
            { 
                return base_value;
            }
            set
            { 
                base_value = value; 
                OnPropertyChanged(nameof(Value_b));
                if (base_value == 0) 
                { 
                    Visible = false; 
                } 
                else 
                { 
                    Visible = true; 
                } 
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new 
            PropertyChangedEventArgs(propertyName));
        }
    }
于 2020-01-12T14:20:57.013 回答