WPF。(WPF. Changing CheckBox IsChecked through MultiBinding doesn't triger CheckBox Command)

编程入门 行业动态 更新时间:2024-10-28 13:16:49
WPF。(WPF. Changing CheckBox IsChecked through MultiBinding doesn't triger CheckBox Command)

我在我的WPF应用程序视图中有Datagrid,我在行标题中使用复选框。

<DataGrid.RowHeaderTemplate> <DataTemplate> <Grid > <CheckBox BorderThickness="0" Command="{Binding DataContext.AssignPartsToGroupCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" > <CheckBox.CommandParameter> <MultiBinding Converter="{StaticResource PartsGroupAssignConverter}"> <Binding Path="IsChecked" RelativeSource="{RelativeSource Self}" Mode="OneWay"/> <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}" Path="DataContext" Mode="OneWay"/> </MultiBinding> </CheckBox.CommandParameter> <CheckBox.IsChecked> <MultiBinding Converter="{StaticResource PartsGroupAssignedConverter}" Mode="OneWay"> <Binding ElementName="partsGroupGrid" Path="SelectedItem.id"></Binding> <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}" Path="DataContext" Mode="OneWay"/> <Binding Path="IsSelected" Mode="OneWay" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}" /> </MultiBinding> </CheckBox.IsChecked> </CheckBox> </Grid> </DataTemplate>

如您所见,我将CheckBox属性“IsSelected”绑定到多个值,其中一个是DataGrid行选择:

<Binding Path="IsSelected" Mode="OneWay" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}" />

我的问题是 - 当我通过选择行检查CheckBox时,不会触发链接到CheckBox的命令。 但是当我手动(使用鼠标)时它会触发。 我该如何解决这个问题?

I have Datagrid in my WPF app view where I use check boxes in row headers.

<DataGrid.RowHeaderTemplate> <DataTemplate> <Grid > <CheckBox BorderThickness="0" Command="{Binding DataContext.AssignPartsToGroupCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" > <CheckBox.CommandParameter> <MultiBinding Converter="{StaticResource PartsGroupAssignConverter}"> <Binding Path="IsChecked" RelativeSource="{RelativeSource Self}" Mode="OneWay"/> <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}" Path="DataContext" Mode="OneWay"/> </MultiBinding> </CheckBox.CommandParameter> <CheckBox.IsChecked> <MultiBinding Converter="{StaticResource PartsGroupAssignedConverter}" Mode="OneWay"> <Binding ElementName="partsGroupGrid" Path="SelectedItem.id"></Binding> <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}" Path="DataContext" Mode="OneWay"/> <Binding Path="IsSelected" Mode="OneWay" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}" /> </MultiBinding> </CheckBox.IsChecked> </CheckBox> </Grid> </DataTemplate>

As you can see I bind CheckBox property "IsSelected" to multiple values and one of them is DataGrid row selection:

<Binding Path="IsSelected" Mode="OneWay" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}" />

My problem is - the command linked to CheckBox is not triggered when I check CheckBox by selecting row. But it triggers when I do it manually (with mouse). How can I solve this?

最满意答案

根据CheckBox源代码,不支持所需的方法 - 只有在单击它之后才会调用该命令。

但是,您可以创建一个小的CheckBox后代来实现您需要的行为。 此后代将跟踪CheckBox.IsChecked属性的更改并执行命令。

你可以这样做:

public class MyCheckBox : CheckBox { static MyCheckBox() { IsCheckedProperty.OverrideMetadata(typeof(MyCheckBox), new FrameworkPropertyMetadata((o, e) => ((MyCheckBox)o).OnIsCheckedChanged())); } readonly Locker toggleLocker = new Locker(); readonly Locker clickLocker = new Locker(); void OnIsCheckedChanged() { if (clickLocker.IsLocked) return; using (toggleLocker.Lock()) { OnClick(); } } protected override void OnToggle() { if (toggleLocker.IsLocked) return; base.OnToggle(); } protected override void OnClick() { using (clickLocker.Lock()) { base.OnClick(); } } }

而洛克班:

class Locker : IDisposable { int count = 0; public bool IsLocked { get { return count != 0; } } public IDisposable Lock() { count++; return this; } public void Dispose() { count--; } }

According to the CheckBox source codes, the desired approach is not supported - a command will be called only after clicking on it.

However, you can create a small CheckBox descendant to achieve the behavior you need. This descendant will track changes of the CheckBox.IsChecked property and execute a command.

You can do it like this:

public class MyCheckBox : CheckBox { static MyCheckBox() { IsCheckedProperty.OverrideMetadata(typeof(MyCheckBox), new FrameworkPropertyMetadata((o, e) => ((MyCheckBox)o).OnIsCheckedChanged())); } readonly Locker toggleLocker = new Locker(); readonly Locker clickLocker = new Locker(); void OnIsCheckedChanged() { if (clickLocker.IsLocked) return; using (toggleLocker.Lock()) { OnClick(); } } protected override void OnToggle() { if (toggleLocker.IsLocked) return; base.OnToggle(); } protected override void OnClick() { using (clickLocker.Lock()) { base.OnClick(); } } }

And the Locker class:

class Locker : IDisposable { int count = 0; public bool IsLocked { get { return count != 0; } } public IDisposable Lock() { count++; return this; } public void Dispose() { count--; } }

更多推荐

本文发布于:2023-07-22 07:02:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1217941.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:CheckBox   Changing   WPF   IsChecked   Command

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!