stevenjin 2023-01-15 14:36 采纳率: 97.6%
浏览 18
已结题

wpf中三态按钮实现

wpf中, 按钮需要切换开、关、无状态三种形式
大概思路是怎样的?

  • 写回答

1条回答 默认 最新

  • m0_54204465 2023-01-15 14:51
    关注

    在 WPF 中实现三态按钮需要使用一些自定义代码。下面是一个大概的思路:

    创建一个类继承自 Button,并为其添加一个依赖属性,来表示按钮的状态。
    使用 DataTrigger 来监听这个依赖属性的变化,并根据变化来更改按钮的样式。
    在按钮的事件处理程序中,更新按钮状态的依赖属性。
    示例代码:

    using System.Windows;
    using System.Windows.Controls;
    
    namespace WpfApp
    {
        public class ThreeStateButton : Button
        {
            public static readonly DependencyProperty StateProperty =
                DependencyProperty.Register("State", typeof(int), typeof(ThreeStateButton), new PropertyMetadata(0));
    
            public int State
            {
                get { return (int)GetValue(StateProperty); }
                set { SetValue(StateProperty, value); }
            }
    
            static ThreeStateButton()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(ThreeStateButton), new FrameworkPropertyMetadata(typeof(ThreeStateButton)));
            }
        }
    }
    
    

    XAML

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:local="clr-namespace:WpfApp">
        <Style TargetType="{x:Type local:ThreeStateButton}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:ThreeStateButton}">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal" />
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border">
                                                <EasingColorKeyFrame KeyTime="0" Value="{StaticResource MouseOverBrush}"/>
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard><ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border">
                                                <EasingColorKeyFrame KeyTime="0" Value="{StaticResource PressedBrush}"/>
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="CheckStates">
                                    <VisualState x:Name="Checked">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="checkMark">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unchecked">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="checkMark">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Indeterminate">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="indeterminateMark">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Border x:Name="border"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    BorderThickness="{TemplateBinding BorderThickness}">
                                <ContentPresenter x:Name="contentPresenter"
                                                  Content="{TemplateBinding Content}"
                                                  ContentTemplate="{TemplateBinding ContentTemplate}"
                                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                  Margin="{TemplateBinding Padding}"
                                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Border>
                            <Path x:Name="checkMark"
                                  Data="M0,123 L39,82 L124,164 L256,18 L295,57 L124,240 z"
                                  Fill="{TemplateBinding Foreground}"
                                  Visibility="Collapsed"
                                  Stretch="Uniform"
                                  StrokeThickness="1"
                                  IsHitTestVisible="False"
                                  HorizontalAlignment="Right"
                                  VerticalAlignment="Center"
                                  Margin="4"/>
                            <Path x:Name="indeterminateMark"
                                  Data="M0,0 L50,50 M50,0 L0,50"
                                  Visibility="Collapsed"
                                  Stretch="Uniform"
                                  Stro
    
    
    

    接下来是在 XAML 中使用这个三态按钮的示例:

    
    <local:ThreeStateButton State="{Binding MyButtonState}" Content="My Three State Button" Click="ThreeStateButton_Click"/>
    

    在这里,我们绑定了按钮的 State 属性到一个名为 MyButtonState 的属性上。在按钮被点击时,我们可以在 Click 事件处理程序中更新这个属性来改变按钮的状态。

    
    
    private void ThreeStateButton_Click(object sender, RoutedEventArgs e)
    {
        ThreeStateButton button = sender as ThreeStateButton;
        if(button.State == 0)
        {
            button.State = 1;
        }
        else if(button.State == 1)
        {
            button.State = 2;
        }
        else
        {
            button.State = 0;
        }
    }
    

    这是一个大概的思路,实际实现中可能还需要根据具体需求进行调整。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 1月23日
  • 已采纳回答 1月15日
  • 创建了问题 1月15日

悬赏问题

  • ¥15 根据以下文字信息,做EA模型图
  • ¥15 删除虚拟显示器驱动 删除所有 Xorg 配置文件 删除显示器缓存文件 重启系统 可是依旧无法退出虚拟显示器
  • ¥15 vscode程序一直报同样的错,如何解决?
  • ¥15 关于使用unity中遇到的问题
  • ¥15 开放世界如何写线性关卡的用例(类似原神)
  • ¥15 关于并联谐振电磁感应加热
  • ¥60 请查询全国几个煤炭大省近十年的煤炭铁路及公路的货物周转量
  • ¥15 请帮我看看我这道c语言题到底漏了哪种情况吧!
  • ¥60 关机时蓝屏并显示KMODE_EXCEPTION_NOT_HANDLED,怎么修?
  • ¥66 如何制作支付宝扫码跳转到发红包界面