You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MaterialDesign WPF菜单按钮样式问题:切换后无法重置原样式

你遇到的核心问题是把按钮的Style设为null时,它会回到WPF的默认基础样式,而不是Material Design的原始按钮样式。这就是为什么你重置后按钮看起来不对的原因。下面给你几种解决方案,从简单到更优雅的都有:

方案1:保存原始样式,切换时复用

首先在窗口/用户控件初始化时,把每个按钮的Material Design原始样式保存下来,之后需要重置时赋值回去,而不是设为null。

步骤1:保存原始样式

在你的窗口构造函数里添加代码:

private Style _originalUserStyle;
private Style _originalAutoStyle;
private Style _originalClientStyle;
private Style _originalFailureStyle;
private Style _originalSettingsStyle;

public YourWindowName()
{
    InitializeComponent();
    // 保存每个按钮的初始Material Design样式
    _originalUserStyle = User_B.Style;
    _originalAutoStyle = Auto_B.Style;
    _originalClientStyle = Clien_B.Style;
    _originalFailureStyle = Failure_B.Style;
    _originalSettingsStyle = Settings_B.Style;
}

步骤2:修改点击事件代码

创建选中样式时,基于原始样式继承(这样能保留Material Design按钮的hover、press等交互状态),重置时用保存的原始样式:

private void User_B_Click(object sender, RoutedEventArgs e)
{
    // 基于原始样式创建选中样式,保留Material Design的交互特性
    Style selectedStyle = new Style(typeof(Button), _originalUserStyle);
    selectedStyle.Setters.Add(new Setter(Button.BackgroundProperty, new SolidColorBrush((Color)ColorConverter.ConvertFromString("#303030"))));
    selectedStyle.Setters.Add(new Setter(Button.ForegroundProperty, new SolidColorBrush((Color)ColorConverter.ConvertFromString("#d50000"))));

    // 应用选中样式到当前按钮,其他按钮重置为原始样式
    User_B.Style = selectedStyle;
    Auto_B.Style = _originalAutoStyle;
    Clien_B.Style = _originalClientStyle;
    Failure_B.Style = _originalFailureStyle;
    Settings_B.Style = _originalSettingsStyle;

    // 导航逻辑
    Main.Navigate(new YourUserPage());
}

private void Auto_B_Click(object sender, RoutedEventArgs e)
{
    Style selectedStyle = new Style(typeof(Button), _originalAutoStyle);
    selectedStyle.Setters.Add(new Setter(Button.BackgroundProperty, new SolidColorBrush((Color)ColorConverter.ConvertFromString("#303030"))));
    selectedStyle.Setters.Add(new Setter(Button.ForegroundProperty, new SolidColorBrush((Color)ColorConverter.ConvertFromString("#d50000"))));

    Auto_B.Style = selectedStyle;
    User_B.Style = _originalUserStyle;
    Clien_B.Style = _originalClientStyle;
    Failure_B.Style = _originalFailureStyle;
    Settings_B.Style = _originalSettingsStyle;

    Main.Navigate(new YourAutoPage());
}

方案2:在XAML中定义样式,更易维护

把默认样式和选中样式都定义在XAML资源里,这样样式管理更清晰,代码也更简洁。

步骤1:添加样式资源

在窗口的<Window.Resources>里添加:

<!-- 继承Material Design的默认扁平按钮样式 -->
<Style x:Key="DefaultMenuButtonStyle" TargetType="Button" BasedOn="{StaticResource MaterialDesignFlatButton}">
    <Setter Property="MinWidth" Value="100"/>
    <!-- 这里可以设置默认的背景/前景,和Material Design保持一致 -->
</Style>

<!-- 选中状态的样式,基于默认样式修改 -->
<Style x:Key="SelectedMenuButtonStyle" TargetType="Button" BasedOn="{StaticResource DefaultMenuButtonStyle}">
    <Setter Property="Background" Value="#303030"/>
    <Setter Property="Foreground" Value="#d50000"/>
</Style>

步骤2:给按钮应用默认样式

修改你的按钮XAML:

<StackPanel Orientation="Horizontal" Height="35" VerticalAlignment="Top">
    <Button x:Name="User_B" Content="Users" Style="{StaticResource DefaultMenuButtonStyle}" Click="User_B_Click"/>
    <Button x:Name="Auto_B" Content="Auto" Style="{StaticResource DefaultMenuButtonStyle}" Click="Auto_B_Click"/>
    <Button x:Name="Clien_B" Content="Client" Style="{StaticResource DefaultMenuButtonStyle}" Click="Clien_B_Click"/>
    <Button x:Name="Failure_B" Content="Failure" Style="{StaticResource DefaultMenuButtonStyle}" Click="Failure_B_Click"/>
    <Button x:Name="Settings_B" Content="Settings" Style="{StaticResource DefaultMenuButtonStyle}" Click="Settings_B_Click"/>
</StackPanel>

步骤3:简化点击事件代码

现在切换样式只需要直接引用资源即可:

private void User_B_Click(object sender, RoutedEventArgs e)
{
    // 应用选中样式到当前按钮,其他按钮用默认样式
    User_B.Style = (Style)FindResource("SelectedMenuButtonStyle");
    Auto_B.Style = (Style)FindResource("DefaultMenuButtonStyle");
    Clien_B.Style = (Style)FindResource("DefaultMenuButtonStyle");
    Failure_B.Style = (Style)FindResource("DefaultMenuButtonStyle");
    Settings_B.Style = (Style)FindResource("DefaultMenuButtonStyle");

    Main.Navigate(new YourUserPage());
}

private void Auto_B_Click(object sender, RoutedEventArgs e)
{
    Auto_B.Style = (Style)FindResource("SelectedMenuButtonStyle");
    User_B.Style = (Style)FindResource("DefaultMenuButtonStyle");
    Clien_B.Style = (Style)FindResource("DefaultMenuButtonStyle");
    Failure_B.Style = (Style)FindResource("DefaultMenuButtonStyle");
    Settings_B.Style = (Style)FindResource("DefaultMenuButtonStyle");

    Main.Navigate(new YourAutoPage());
}

方案3:用ToggleButton实现单选菜单(最优雅)

这种方式利用WPF的ToggleButton和单选组特性,自动管理选中状态,不需要手动重置其他按钮的样式,代码量最少。

步骤1:定义ToggleButton样式

在<Window.Resources>里添加:

<Style x:Key="MenuToggleButtonStyle" TargetType="ToggleButton" BasedOn="{StaticResource MaterialDesignFlatToggleButton}">
    <Setter Property="MinWidth" Value="100"/>
    <!-- 默认状态样式,和Material Design保持一致 -->
    <Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"/>
    <Setter Property="Foreground" Value="{DynamicResource MaterialDesignBody}"/>
    
    <!-- 选中状态触发器 -->
    <Style.Triggers>
        <Trigger Property="IsChecked" Value="True">
            <Setter Property="Background" Value="#303030"/>
            <Setter Property="Foreground" Value="#d50000"/>
        </Trigger>
    </Style.Triggers>
</Style>

步骤2:替换Button为ToggleButton,并设置GroupName

同一个GroupName的ToggleButton会自动实现单选效果:

<StackPanel Orientation="Horizontal" Height="35" VerticalAlignment="Top">
    <ToggleButton x:Name="User_B" Content="Users" Style="{StaticResource MenuToggleButtonStyle}" GroupName="MainMenu" Click="User_B_Click"/>
    <ToggleButton x:Name="Auto_B" Content="Auto" Style="{StaticResource MenuToggleButtonStyle}" GroupName="MainMenu" Click="Auto_B_Click"/>
    <ToggleButton x:Name="Clien_B" Content="Client" Style="{StaticResource MenuToggleButtonStyle}" GroupName="MainMenu" Click="Clien_B_Click"/>
    <ToggleButton x:Name="Failure_B" Content="Failure" Style="{StaticResource MenuToggleButtonStyle}" GroupName="MainMenu" Click="Failure_B_Click"/>
    <ToggleButton x:Name="Settings_B" Content="Settings" Style="{StaticResource MenuToggleButtonStyle}" GroupName="MainMenu" Click="Settings_B_Click"/>
</StackPanel>

步骤3:简化代码,只处理导航

现在不需要管理样式切换,WPF会自动处理选中状态:

private void User_B_Click(object sender, RoutedEventArgs e)
{
    Main.Navigate(new YourUserPage());
}

private void Auto_B_Click(object sender, RoutedEventArgs e)
{
    Main.Navigate(new YourAutoPage());
}

// 其他按钮的点击事件同理,只需要处理导航逻辑

这样实现的效果完全符合你想要的示例图,而且样式和交互都保留了Material Design的特性,代码也更简洁易维护。

内容的提问来源于stack exchange,提问作者J_Goblin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 18:45:48