整合指南
本頁說明 MahApps.Metro 與其他框架、工具的整合方式。
MVVM 框架整合
搭配 CommunityToolkit.Mvvm
CommunityToolkit.Mvvm(前身 Microsoft.Toolkit.Mvvm)是目前推薦的輕量 MVVM 框架。
dotnet add package CommunityToolkit.Mvvm
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MahApps.Metro.Controls.Dialogs;
public partial class DeviceMonitorViewModel : ObservableObject
{
private readonly IDialogCoordinator _dialogCoordinator;
[ObservableProperty]
private double _temperature;
[ObservableProperty]
private bool _isConnected;
[ObservableProperty]
private bool _isSettingsOpen;
public DeviceMonitorViewModel(IDialogCoordinator dialogCoordinator)
{
_dialogCoordinator = dialogCoordinator;
}
[RelayCommand]
private void ToggleSettings()
{
IsSettingsOpen = !IsSettingsOpen;
}
[RelayCommand]
private async Task EmergencyStop()
{
var result = await _dialogCoordinator.ShowMessageAsync(
this,
"緊急停機",
"確定要執行緊急停機?所有設備將立即停止。",
MessageDialogStyle.AffirmativeAndNegative);
if (result == MessageDialogResult.Affirmative)
{
await StopAllDevicesAsync();
}
}
}
搭配 ReactiveUI
如果專案同時使用 Rx.NET,ReactiveUI 是更好的搭配:
dotnet add package ReactiveUI.WPF
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
public class DeviceViewModel : ReactiveObject
{
[Reactive]
public double Temperature { get; set; }
[Reactive]
public bool IsConnected { get; set; }
public ReactiveCommand<Unit, Unit> StopCommand { get; }
public DeviceViewModel()
{
var canStop = this.WhenAnyValue(x => x.IsConnected);
StopCommand = ReactiveCommand.CreateFromTask(
StopDeviceAsync, canStop);
}
}
MahApps.Metro.IconPacks 整合
IconPacks 提供數千個向量圖示,支援 Material Design、FontAwesome、Unicons 等多種圖示集。
安裝
# 只安裝 Material Design 圖示(推薦,檔案小)
dotnet add package MahApps.Metro.IconPacks.Material
# 或安裝全部圖示集(檔案較大)
dotnet add package MahApps.Metro.IconPacks
XAML namespace
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
使用
<!-- 基本圖示 -->
<iconPacks:PackIconMaterial Kind="Thermometer" Width="24" Height="24" />
<!-- 在按鈕中使用 -->
<Button Style="{StaticResource MahApps.Styles.Button.Circle}">
<iconPacks:PackIconMaterial Kind="Play" />
</Button>
<!-- 搭配文字 -->
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="AlertCircle" Foreground="Red"
VerticalAlignment="Center" Margin="0,0,4,0" />
<TextBlock Text="溫度超過上限" VerticalAlignment="Center" />
</StackPanel>
常用圖示對照
| 場景 | Kind 值 | 說明 |
|---|---|---|
| 設備連線 | LanConnect / LanDisconnect | 連線/斷線 |
| 設備運轉 | Play / Stop / Pause | 啟動/停止/暫停 |
| 溫度 | Thermometer | 溫度計 |
| 警報 | AlertCircle / BellRing | 告警 |
| 設定 | Cog / CogOutline | 齒輪 |
| 儀表板 | ViewDashboard | 面板 |
| 圖表 | ChartLine / ChartBar | 折線/長條圖 |
| 匯出 | FileExport / Download | 匯出/下載 |
| 搜尋 | Magnify | 放大鏡 |
| 重新整理 | Refresh | 重新載入 |
多語系支援
搭配 .resx 資源檔
<!-- 使用 x:Static 綁定資源 -->
<mah:Flyout Header="{x:Static props:Resources.DeviceSettings}" ... />
<Button Content="{x:Static props:Resources.StartDevice}" />
搭配動態語系切換
// 切換語系
public void ChangeLanguage(string cultureCode)
{
var culture = new CultureInfo(cultureCode);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
// 通知所有綁定更新
// 使用 CommunityToolkit.Mvvm 的 Messenger 或 EventAggregator
}
MahApps 控件的本地化
MahApps 的內建文字(如 Dialog 的 OK/Cancel)可透過 MetroDialogSettings 自訂:
var settings = new MetroDialogSettings
{
AffirmativeButtonText = "確定",
NegativeButtonText = "取消",
FirstAuxiliaryButtonText = "略過",
};
效能注意事項
大量控件時使用 VirtualizingStackPanel
<!-- DataGrid 預設就有虛擬化,但要確認沒有關掉 -->
<DataGrid VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
EnableRowVirtualization="True"
EnableColumnVirtualization="True" />
<!-- ListBox/ItemsControl 加上虛擬化 -->
<ListBox VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.CanContentScroll="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
減少 ResourceDictionary 載入
只載入需要的資源,不要載入全部:
<!-- ✅ 只載入需要的 -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<!-- ❌ 不要額外載入不需要的主題 -->
<!-- 只載入一個主題就好,不要全部載入 -->
Flyout 的 CloseButtonVisibility
大量 Flyout 時,設定 CloseButtonVisibility="Collapsed" 減少不必要的元素:
<mah:Flyout CloseButtonVisibility="Collapsed"
IsPinned="False"
ExternalCloseButton="Left" />
避免過多動畫
在嵌入式或低規格工控機上,動畫可能影響效能:
<!-- 關閉特定轉場動畫 -->
<mah:MetroWindow
mah:MetroWindow.IsCloseButtonEnabled="True"
WindowTransitionsEnabled="False">
與 ComponentOne 共存
公司專案可能同時使用 MahApps.Metro 和 ComponentOne (C1.WPF)。兩者的樣式可能衝突。
解法:明確指定控件樣式
<!-- 確保 C1 FlexGrid 不受 MahApps 影響 -->
<c1:C1FlexGrid Style="{x:Null}" ... />
<!-- 對於標準控件,明確使用 MahApps 樣式 -->
<Button Style="{StaticResource MahApps.Styles.Button}" />
載入順序
在 App.xaml 中,MahApps 資源放前面,C1 資源放後面:
<ResourceDictionary.MergedDictionaries>
<!-- 1. MahApps -->
<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" />
<!-- 2. ComponentOne(後載入覆蓋衝突) -->
<ResourceDictionary Source="/C1Themes;component/MetroDark.xaml" />
<!-- 3. 自訂覆寫(最後載入,最高優先) -->
<ResourceDictionary Source="Styles/CustomOverrides.xaml" />
</ResourceDictionary.MergedDictionaries>
延伸閱讀:
- 概觀與安裝 — MetroWindow 設定與主題系統
- 常用控件 — 各控件用法詳解
- ComponentOne 使用指南 — C1.WPF 控件