如何在WPF中绑定反布尔属性?
我拥有的是具有IsReadOnly
属性的对象。 如果这个属性是真的,我想将button(例如)上的IsEnabled
属性设置为false。
我想相信我可以像IsEnabled="{Binding Path=!IsReadOnly}"
一样轻松地做到这一点,但是WPF不能。
我是降级到必须通过所有的样式设置? 只是把一个布尔设置为另一个布尔的倒数而已,太罗嗦了。
<Button.Style> <Style TargetType="{x:Type Button}"> <Style.Triggers> <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="True"> <Setter Property="IsEnabled" Value="False" /> </DataTrigger> <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="False"> <Setter Property="IsEnabled" Value="True" /> </DataTrigger> </Style.Triggers> </Style> </Button.Style>
你可以使用一个ValueConverter来为你反转一个bool属性。
XAML:
IsEnabled="{Binding Path=IsReadOnly, Converter={StaticResource InverseBooleanConverter}}"
转换器:
[ValueConversion(typeof(bool), typeof(bool))] public class InverseBooleanConverter: IValueConverter { #region IValueConverter Members public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (targetType != typeof(bool)) throw new InvalidOperationException("The target must be a boolean"); return !(bool)value; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotSupportedException(); } #endregion }
你有没有考虑过IsNotReadOnly财产? 如果被绑定的对象是MVVM域中的ViewModel,那么附加属性就非常合理。 如果它是一个直接的实体模型,您可以考虑组合并向表单呈现实体的专门视图模型。
用standart绑定你需要使用看起来有点风的转换器。 所以,我build议你看看我的项目CalcBinding ,这是专门开发解决这个问题和其他一些问题。 使用高级绑定,您可以直接在xaml中编写具有多个源属性的expression式。 说,你可以写一些像:
<Button IsEnabled="{c:Binding Path=!IsReadOnly}" />
要么
<Button Content="{c:Binding ElementName=grid, Path=ActualWidth+Height}"/>
要么
<Label Content="{c:Binding A+B+C }" />
要么
<Button Visibility="{c:Binding IsChecked, FalseToVisibility=Hidden}" />
其中A,B,C,IsChecked – viewModel的属性,它将正常工作
祝你好运!
我会build议使用https://quickconverter.codeplex.com/
反转布尔值就是<Button IsEnabled="{qc:Binding '!$P', P={Binding IsReadOnly}}" />
简单: <Button IsEnabled="{qc:Binding '!$P', P={Binding IsReadOnly}}" />
这加快了写入转换器通常需要的时间。
我希望我的XAML尽可能保持优雅,所以我创build了一个类来包装驻留在我的一个共享库中的bool,隐式运算符允许该类在代码隐藏中无缝地用作bool
public class InvertableBool { private bool value = false; public bool Value { get { return value; } } public bool Invert { get { return !value; } } public InvertableBool(bool b) { value = b; } public static implicit operator InvertableBool(bool b) { return new InvertableBool(b); } public static implicit operator bool(InvertableBool b) { return b.value; } }
只需要你的项目的变化是使你想要反转的财产返回这个而不是布尔
public InvertableBool IsActive { get { return true; } }
在XAML后缀与价值或反转的绑定
IsEnabled="{Binding IsActive.Value}" IsEnabled="{Binding IsActive.Invert}"
这个也适用于可空的布尔。
[ValueConversion(typeof(bool?), typeof(bool))] public class InverseBooleanConverter : IValueConverter { #region IValueConverter Members public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (targetType != typeof(bool?)) { throw new InvalidOperationException("The target must be a nullable boolean"); } bool? b = (bool?)value; return b.HasValue && !b.Value; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return !(value as bool?); } #endregion }
不知道这是否与XAML相关,但在我简单的Windows应用程序中,我手动创build了绑定,并添加了一个Format事件处理程序。
public FormMain() { InitializeComponent(); Binding argBinding = new Binding("Enabled", uxCheckBoxArgsNull, "Checked", false, DataSourceUpdateMode.OnPropertyChanged); argBinding.Format += new ConvertEventHandler(Binding_Format_BooleanInverse); uxTextBoxArgs.DataBindings.Add(argBinding); } void Binding_Format_BooleanInverse(object sender, ConvertEventArgs e) { bool boolValue = (bool)e.Value; e.Value = !boolValue; }
在您的视图模型中添加一个属性,这将返回反向值。 并将其绑定到button。 喜欢;
在视图模型中:
public bool IsNotReadOnly{get{return !IsReadOnly;}}
在xaml中:
IsEnabled="{Binding IsNotReadOnly"}
我有一个倒置问题,但一个整洁的解决scheme。
动机是,XAMLdevise师将显示一个空的控制,例如,当没有datacontext /没有MyValues
(itemssource)。
初始代码:当MyValues
为空时隐藏控制。 改进的代码:当MyValues
不为空或空时显示控制。
当然,问题是如何expression“一个或多个项目”,这与0项目相反。
<ListBox ItemsSource={Binding MyValues}"> <ListBox.Style x:Uid="F404D7B2-B7D3-11E7-A5A7-97680265A416"> <Style TargetType="{x:Type ListBox}"> <Style.Triggers> <DataTrigger Binding="{Binding MyValues.Count}"> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Style.Triggers> </Style> </ListBox.Style> </ListBox>
我解决了它通过添加:
<DataTrigger Binding="{Binding MyValues.Count, FallbackValue=0, TargetNullValue=0}">
Ergo设置绑定的默认值。 当然这不适用于所有types的逆向问题,但是用干净的代码帮助我。