是否有一种方法可以使用现有的WPF BooleanToVisibilityConverter转换器,但将False值转换为Hidden,而不是默认的Collapsed,还是我应该自己编写?我正在一个项目上工作,在这个项目中,做这样简单的事情会产生很大的开销(共享的东西放在一个单独的解决方案中,重建/检入/合并过程是一个过度膨胀的巨兽级过程),因此我更喜欢如果我可以只通过传递参数来使用现有的转换器,而不必跳过刚才提到的障碍。
是否有一种方法可以使用现有的WPF BooleanToVisibilityConverter转换器,但将False值转换为Hidden,而不是默认的Collapsed,还是我应该自己编写?我正在一个项目上工作,在这个项目中,做这样简单的事情会产生很大的开销(共享的东西放在一个单独的解决方案中,重建/检入/合并过程是一个过度膨胀的巨兽级过程),因此我更喜欢如果我可以只通过传递参数来使用现有的转换器,而不必跳过刚才提到的障碍。
我发现最简单和最好的解决方案是这样的:
[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中也不是严格必需的,但与内置转换器保持一致。
IsItFridayAlready
是你通过本地设置为DataContext的任何内容绑定到的某个属性。在绑定表达式中,它代表要绑定的路径。 - Drew Noakes#if !SILVERLIGHT [ValueConversion(typeof(bool), typeof(Visibility))] #endif
- Kamil很遗憾,它只能转换为Visible或Collapsed,因此您需要编写自己的方法。以下是根据Reflector提供的Convert方法:
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);
}
(value is bool?)
的检查是不必要的。
如果一个可空布尔值作为参数传递,它会自动转换为普通布尔值,如果该值被设置,则第一个检查将成功。
如果该值未被设置(即为null),则它是一个对象,两个检查都将失败。 - memory of a dreamVisibility.Hidden
。 - JansthcirlU你能不能使用样式而不是转换器?代码将类似于:
<Style x:Key="Triggers" TargetType="Button">
<Style.Triggers>
<Trigger Property="{Binding ...}" Value="false">
<Setter Property = "Visibility" Value="Hidden"/>
</Trigger>
</Style.Triggers>
</Style>
您需要自己提供属性绑定,以指向您的布尔属性。
我喜欢使用参数来反转可见性逻辑: 只需在xaml代码中加入:ConverterParameter=Reverse即可反转逻辑。
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);
}
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}}"
<Button x:Name="SelectBinaryFilePath" Content="Select" Visibility="{Binding CanSelectBinaryFile}" />
public Visibility CanSelectBinaryFile
{
get
{
return String.IsNullOrEmpty(FileSystemPath) ? Visibility.Hidden : Visibility.Visible;
}
}
确保执行NotifyOfPropertyChange
以确保更新CanSelectBinaryFile
属性。
我遇到了这个问题,我的解决方案可能非常特殊,但我还是愿意分享一下。由于我的情况,我能够通过一小段代码模仿转换器,而不需要真正的转换器。只有在绑定到文本框的变量使数字框(通过正则表达式确保其为数字)不为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));
}
}