Skip to main content

MahApps.Metro WPF UI 指南

用途:為 WPF 應用程式提供 Modern UI(Metro / Fluent 風格)外觀

NuGetMahApps.Metro(目前穩定版 2.4+)

授權:MIT

支援:.NET Framework 4.6.2+、.NET 5+、.NET 6+、.NET 8+


為什麼選 MahApps.Metro

在工業自動化中,我們的 WPF 設備控制介面需要:

  • 清晰的視覺層次(操作員在工廠環境中使用)
  • Dark/Light 主題支援(日班/夜班切換)
  • 豐富的控件(進度指示、開關切換、飛出面板等)
  • 穩定且維護活躍的社群
框架優勢劣勢
MahApps.Metro社群大、控件豐富、穩定風格偏 Metro/Modern
HandyControl控件數量多、中國社群活躍文件多為中文、風格不統一
MaterialDesignXamlMaterial Design 風格精美某些控件與工業場景不搭
WPF UI (Fluent)Win11 Fluent 風格較新、控件還在成長

MahApps.Metro 是公司選擇的標準 UI 框架,提供統一的控件外觀和完整的主題系統。


安裝

dotnet add package MahApps.Metro
dotnet add package MahApps.Metro.IconPacks.Material # 圖示庫(選裝)

基本設定

1. App.xaml — 載入資源字典

<Application x:Class="DeviceControl.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- MahApps.Metro 主題 -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Dark.Blue.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

2. MainWindow — 使用 MetroWindow

<mah:MetroWindow x:Class="DeviceControl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
Title="設備控制台"
Width="1280" Height="800"
WindowStartupLocation="CenterScreen"
GlowBrush="{DynamicResource MahApps.Brushes.Accent}">

<Grid>
<!-- 內容 -->
</Grid>
</mah:MetroWindow>

Code-behind 繼承 MetroWindow

using MahApps.Metro.Controls;

public partial class MainWindow : MetroWindow
{
public MainWindow()
{
InitializeComponent();
}
}

主題系統

MahApps.Metro 的主題由兩部分組成:Base Theme(Light/Dark)和 Accent Color(強調色)。

主題繼承鏈

主題套用從 App.xamlResourceDictionary.MergedDictionaries 向下展開,最終覆蓋到每個 MetroWindow 及其子控制項。ControlzEx.Theming.ThemeManager 是執行期切換主題的入口:

要點整理:

  • Controls.xaml 必須最先載入,否則後續 Theme 字典找不到基底樣式會報錯
  • Theme 字典(Dark.Blue.xaml 等)一次只能存在一個,改主題時由 ThemeManager.ChangeTheme 負責替換
  • 動態切換透過 DynamicResource 綁定—控制項自動感知 Theme 字典變動,無需重啟應用程式

內建主題

格式:{BaseTheme}.{AccentColor}

  • Base Theme:LightDark
  • Accent Color:RedGreenBluePurpleOrangeLimeEmeraldTealCyanCobaltIndigoVioletPinkMagentaCrimsonAmberYellowBrownOliveSteelMauveTaupeSienna

動態切換主題

using ControlzEx.Theming;

// 切換到 Dark + Blue
ThemeManager.Current.ChangeTheme(Application.Current, "Dark.Blue");

// 切換到 Light + Green
ThemeManager.Current.ChangeTheme(Application.Current, "Light.Green");

// 只切換 Base Theme(保留 Accent Color)
var currentTheme = ThemeManager.Current.DetectTheme(Application.Current);
var inverseTheme = ThemeManager.Current.GetInverseTheme(currentTheme);
if (inverseTheme != null)
ThemeManager.Current.ChangeTheme(Application.Current, inverseTheme);

自訂 Accent Color

// 用 RGB 建立自訂強調色
ThemeManager.Current.AddTheme(
RuntimeThemeGenerator.Current.GenerateRuntimeTheme(
"Dark", Color.FromRgb(0x2E, 0x40, 0x57))); // 公司色

ThemeManager.Current.ChangeTheme(Application.Current, "Dark.Runtime");

MVVM 綁定主題切換

// ViewModel
public class SettingsViewModel : ObservableObject
{
private bool _isDarkTheme = true;

public bool IsDarkTheme
{
get => _isDarkTheme;
set
{
if (SetProperty(ref _isDarkTheme, value))
{
var baseTheme = value ? "Dark" : "Light";
ThemeManager.Current.ChangeThemeBaseColor(
Application.Current, baseTheme);
}
}
}
}
<!-- XAML -->
<mah:ToggleSwitch IsOn="{Binding IsDarkTheme}"
OnContent="深色模式"
OffContent="淺色模式" />

MetroWindow 自訂

標題列按鈕

<mah:MetroWindow
ShowMinButton="True"
ShowMaxRestoreButton="True"
ShowCloseButton="True"
ShowIconOnTitleBar="True"
TitleCharacterCasing="Normal">

左側/右側標題命令

<mah:MetroWindow.LeftWindowCommands>
<mah:WindowCommands>
<Button Content="設定" Click="Settings_Click" />
</mah:WindowCommands>
</mah:MetroWindow.LeftWindowCommands>

<mah:MetroWindow.RightWindowCommands>
<mah:WindowCommands>
<Button Content="連線狀態">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Width="8" Height="8"
Fill="{Binding ConnectionColor}" Margin="0,0,5,0"/>
<TextBlock Text="{Binding ConnectionText}" />
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</mah:WindowCommands>
</mah:MetroWindow.RightWindowCommands>

無框視窗(全螢幕儀表板)

<mah:MetroWindow
ShowTitleBar="False"
WindowStyle="None"
AllowsTransparency="True"
ResizeMode="NoResize"
WindowState="Maximized">

控制項分類

MahApps.Metro 提供的控制項依功能可粗略分為以下四類。實際 API 與範例見常用控件

選用指引:

  • 視窗容器:主應用視窗一律繼承 MetroWindow;獨立內容頁面可用 MetroContentControl
  • 面板 / 導航Flyout 適合設定面板、詳細資料;HamburgerMenu 適合主導航
  • 輸入控制項:優先用 ToggleSwitch 取代原生 CheckBox 以維持 Metro 風格;數值輸入用 NumericUpDown 內建邊界驗證
  • 回饋 / 狀態:長時間操作用 ProgressRing;使用者決策用 MetroDialog;紅點提示用 Badged

本指南結構

頁面內容
概觀與安裝(本頁)MetroWindow、主題系統、色彩自訂
常用控件Flyout、Dialog、ProgressRing、ToggleSwitch 等
整合指南MVVM、IconPacks、多語系、效能