首先执行的是:ToggleButton.IsChecked绑定更新,还是命令绑定?

时间:2022-01-27 03:10:16

First - a disclaimer:

首先 - 免责声明:

If you're reading this because you want to use both a binding for IsChecked and a RelayCommand to change things, you probably are doing it wrong. You should be working off of the IsChecked binding's Set() call.

如果您正在阅读此内容,因为您想同时使用IsChecked的绑定和RelayCommand来更改内容,那么您可能做错了。您应该使用IsChecked绑定的Set()调用。

The question:

问题是:

I have a ToggleButton in which there's both a binding for IsChecked and for a Command:

我有一个ToggleButton,其中既有IsChecked的绑定,也有Command的绑定:

<ToggleButton IsChecked="{Binding BooleanBackedProperty}" 
         Command="{Binding SomeCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
         CommandParameter="{Binding}" />

Yes - I know, tsk tsk. Couldn't be helped.

是的 - 我知道,tsk tsk。无法帮助。

When the user clicks the ToggleButton, which these two is going to fire first? Is the Command going to be executed, or is the IsChecked binding going to update the bound property? Or - is this actually similar to the post on social in which it creates a race condition?

当用户点击ToggleButton时,这两个将首先触发? Command是否会被执行,或者IsChecked绑定是否会更新绑定属性?或者 - 这实际上类似于社交中创造竞争条件的帖子吗?

1 个解决方案

#1


4  

IsChecked will have a valid value at the command run time.

IsChecked在命令运行时将具有有效值。

ToggleButton overrides OnClick from ButtonBase like this:

ToggleButton从ButtonBase重写OnClick,如下所示:

    protected override void OnClick()
    {
        OnToggle();
        base.OnClick();
    }

OnToggle is the method that updates IsChecked:

OnToggle是更新IsChecked的方法:

    protected internal virtual void OnToggle()
    {
        // If IsChecked == true && IsThreeState == true   --->  IsChecked = null
        // If IsChecked == true && IsThreeState == false  --->  IsChecked = false
        // If IsChecked == false                          --->  IsChecked = true
        // If IsChecked == null                           --->  IsChecked = false
        bool? isChecked;
        if (IsChecked == true)
            isChecked = IsThreeState ? (bool?)null : (bool?)false;
        else // false or null
            isChecked = IsChecked.HasValue; // HasValue returns true if IsChecked==false
        SetCurrentValueInternal(IsCheckedProperty, isChecked);
    }

And the base OnClick fires the command:

基础OnClick会触发命令:

    protected virtual void OnClick()
    {
        RoutedEventArgs newEvent = new RoutedEventArgs(ButtonBase.ClickEvent, this);
        RaiseEvent(newEvent);

        MS.Internal.Commands.CommandHelpers.ExecuteCommandSource(this);
    }

Source: MSDN Reference Source

来源:MSDN参考资料来源

So the value should be valid by the time the command runs.

因此,该值应在命令运行时有效。

#1


4  

IsChecked will have a valid value at the command run time.

IsChecked在命令运行时将具有有效值。

ToggleButton overrides OnClick from ButtonBase like this:

ToggleButton从ButtonBase重写OnClick,如下所示:

    protected override void OnClick()
    {
        OnToggle();
        base.OnClick();
    }

OnToggle is the method that updates IsChecked:

OnToggle是更新IsChecked的方法:

    protected internal virtual void OnToggle()
    {
        // If IsChecked == true && IsThreeState == true   --->  IsChecked = null
        // If IsChecked == true && IsThreeState == false  --->  IsChecked = false
        // If IsChecked == false                          --->  IsChecked = true
        // If IsChecked == null                           --->  IsChecked = false
        bool? isChecked;
        if (IsChecked == true)
            isChecked = IsThreeState ? (bool?)null : (bool?)false;
        else // false or null
            isChecked = IsChecked.HasValue; // HasValue returns true if IsChecked==false
        SetCurrentValueInternal(IsCheckedProperty, isChecked);
    }

And the base OnClick fires the command:

基础OnClick会触发命令:

    protected virtual void OnClick()
    {
        RoutedEventArgs newEvent = new RoutedEventArgs(ButtonBase.ClickEvent, this);
        RaiseEvent(newEvent);

        MS.Internal.Commands.CommandHelpers.ExecuteCommandSource(this);
    }

Source: MSDN Reference Source

来源:MSDN参考资料来源

So the value should be valid by the time the command runs.

因此,该值应在命令运行时有效。