我拥有的是一个具有IsReadOnly属性的对象。如果此属性为true,我想将按钮上的IsEnabled属性设置为false(例如)。
我愿意相信我可以像IsEnabled="{绑定路径=!IsReadOnly}”,但这与WPF不兼容。
我是否不得不经历所有的样式设置?对于将一个bool值设置为另一个bool值的倒数这样简单的事情来说,似乎太啰嗦了。
<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>
不知道这是否与XAML相关,但在我简单的Windows应用程序中,我手动创建了绑定,并添加了一个格式事件处理程序。
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;
}
I did something very similar. I created my property behind the scenes that enabled the selection of a combobox ONLY if it had finished searching for data. When my window first appears, it launches an async loaded command but I do not want the user to click on the combobox while it is still loading data (would be empty, then would be populated). So by default the property is false so I return the inverse in the getter. Then when I'm searching I set the property to true and back to false when complete.
private bool _isSearching;
public bool IsSearching
{
get { return !_isSearching; }
set
{
if(_isSearching != value)
{
_isSearching = value;
OnPropertyChanged("IsSearching");
}
}
}
public CityViewModel()
{
LoadedCommand = new DelegateCommandAsync(LoadCity, LoadCanExecute);
}
private async Task LoadCity(object pArg)
{
IsSearching = true;
//**Do your searching task here**
IsSearching = false;
}
private bool LoadCanExecute(object pArg)
{
return IsSearching;
}
然后,对于组合框,我可以直接绑定到IsSearching:
<ComboBox ItemsSource="{Binding Cities}" IsEnabled="{Binding IsSearching}" DisplayMemberPath="City" />
我希望我的XAML尽可能保持优雅,所以我创建了一个类来包装驻留在我的一个共享库中的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;
}
}
你的项目需要做的唯一改变就是让你想要反转的属性返回this而不是bool
public InvertableBool IsActive
{
get
{
return true;
}
}
在XAML中,用Value或Invert后缀绑定
IsEnabled="{Binding IsActive.Value}"
IsEnabled="{Binding IsActive.Invert}"
不知道这是否与XAML相关,但在我简单的Windows应用程序中,我手动创建了绑定,并添加了一个格式事件处理程序。
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;
}
对于标准绑定,您需要使用看起来有点风的转换器。所以,我建议你看看我的CalcBinding项目,它是专门解决这个问题和其他一些问题而开发的。使用高级绑定,您可以直接在xaml中编写带有许多源属性的表达式。比如,你可以这样写:
<Button IsEnabled="{c:Binding Path=!IsReadOnly}" />
or
<Button Content="{c:Binding ElementName=grid, Path=ActualWidth+Height}"/>
or
<Label Content="{c:Binding A+B+C }" />
or
<Button Visibility="{c:Binding IsChecked, FalseToVisibility=Hidden}" />
其中A, B, C, IsChecked - viewModel的属性,它将正常工作