WPF ToggleButton不正确的渲染行为

时间:2012-04-04 15:02:54

标签: wpf togglebutton

这里发生了什么,以及如何解决方法?

  1. 按MyToggleButton。现在它看起来像是立即按下(选中)。
  2. 同时MyToggleButton_Checked处理程序禁用MyToggleButton。
  3. 现在按下非切换按钮'启用'。我们看到了什么? MyToggleButton看起来像是启用了。好。但是等等,现在它看起来像是非紧迫的!为什么呢?!
  4. XAML:

    <StackPanel>
    
        <ToggleButton x:Name="MyToggleButton" Content="MyToggleButton" Checked="MyToggleButton_Checked"/>
    
        <TextBlock Text="{Binding IsChecked, ElementName=MyToggleButton}" Margin="0,4"/>
    
        <Button Name="EnableButton" Content="Enable" Click="EnableButton_Click"/>
        <Button Name="DisableButton" Content="Disable" Click="DisableButton_Click"/>
    
    </StackPanel>
    

    代码隐藏:

    void MyToggleButton_Checked(object sender, RoutedEventArgs e)
    {
        MyToggleButton.IsEnabled = false;
    }
    
    
    void EnableButton_Click(object sender, RoutedEventArgs e)
    {
        MyToggleButton.IsEnabled = true;
    }
    
    void DisableButton_Click(object sender, RoutedEventArgs e)
    {
        MyToggleButton.IsEnabled = false;
    }
    

    UPD:

    目前唯一可行的解​​决方法是:

    void EnableButton_Click(object sender, RoutedEventArgs e)
    {
        MyToggleButton.IsEnabled = true;
    
        var controlTemplate = MyToggleButton.Template;
    
        var buttonChrome = (Microsoft.Windows.Themes.ButtonChrome)controlTemplate.FindName("Chrome", MyToggleButton);
    
        buttonChrome.RenderPressed = false;
    
        buttonChrome.RenderPressed = true;
    }
    

    还有其他人吗?

    UPD2:

    另一种解决方法是:

    void EnableButton_Click(object sender, RoutedEventArgs e)
    {
        MyToggleButton.IsEnabled = true;
    
        var controlTemplate = MyToggleButton.Template;
        MyToggleButton.Template = null;
        MyToggleButton.Template = controlTemplate;
    }
    

    但是控件在模板替换时闪烁。

1 个答案:

答案 0 :(得分:6)

这是我解决问题的方法,这里是video,用法:

<StackPanel>
    <ToggleButton x:Name="MyToggleButton" Content="MyToggleButton" Checked="MyToggleButton_Checked"
                    l:CorrectToggleButtonCheckedEnableBehavior.IsActive="True"/>
    <Button Name="EnableButton" Content="Enable" Click="EnableButton_Click"/>
</StackPanel>

和附加的行为源代码:

public static class CorrectToggleButtonCheckedEnableBehavior
{
    public static bool GetIsActive(ToggleButton toggleButton)
    {
        return (bool)toggleButton.GetValue(IsActiveProperty);
    }

    public static void SetIsActive(ToggleButton toggleButton, bool value)
    {
        toggleButton.SetValue(IsActiveProperty, value);
    }

    public static readonly DependencyProperty IsActiveProperty =
        DependencyProperty.RegisterAttached("IsActive", typeof(bool), typeof(CorrectToggleButtonCheckedEnableBehavior),
        new UIPropertyMetadata(false, OnIsActiveChanged));

    static void OnIsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var toggleButton = (ToggleButton)d;

        if (GetIsActive(toggleButton))
        {
            toggleButton.IsEnabledChanged += new DependencyPropertyChangedEventHandler(ToggleButton_IsEnabledChanged);
        }
        else
        {
            toggleButton.IsEnabledChanged -= new DependencyPropertyChangedEventHandler(ToggleButton_IsEnabledChanged);
        }
    }

    static void ToggleButton_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var toggleButton = (ToggleButton)sender;

        if (toggleButton.IsEnabled && (toggleButton.IsChecked ?? false))
        {
            Invalidate(toggleButton);
        }
    }

    static void Invalidate(ToggleButton toggleButton)
    {
        var controlTemplate = toggleButton.Template;
        toggleButton.Template = null;
        toggleButton.Template = controlTemplate;
    }
}