MahApps.Metro WPF 开发使用过程中遇到的问题 - 未能加载文件或程序集“Microsoft.Xaml.Behaviors,
MahApps.Metro WPF 开发使用过程中遇到的问题
- MainWindow.xaml
- MainWindow.xaml.cs
- 报错内容
- 解决方法:
- 方法一:【推荐】安装缺失的 NuGet 包
- 方法二:【不推荐】尝试不使用它(并解释为什么不可行)
- 结论与最终建议
MainWindow.xaml
代码不是测试重点 重点是使用了 MahApps.Metro
<mah:MetroWindowx:Class="gTools.ViewTests.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:local="clr-namespace:gTools.ViewTests"xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"Title="MainWindow"Width="800"Height="450"mc:Ignorable="d"><Grid><UniformGridMargin="5"Columns="9"Rows="9"><!-- 手动添加81个按钮(实际开发建议用代码生成) --><ButtonMargin="2"Click="Button_MessageClick"Content="弹窗测试" /><ButtonMargin="2"Click="Button_GetTimeClick"Content="获取时间" /><!-- 省略其他79个按钮... --><Button Margin="2" Content="9-9" /></UniformGrid></Grid>
</mah:MetroWindow>
MainWindow.xaml.cs
/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : MetroWindow{public MainWindow(){InitializeComponent();}private async void Button_MessageClick(object sender, RoutedEventArgs e){//// 在ViewModel中调用//var messageService = new Message();//await messageService.ShowAsync("保存成功");//var result = await messageService.ShowCheckAsync("确认删除吗?");//if (result == MessageDialogResult.Affirmative)//{// // 用户点击确定//}//// 显示警告气球提示//messageService.ShowBalloonTipWarning("警告", "磁盘空间不足");var msg = new Message();msg.ShowBalloonTipWarning("警告", "磁盘空间不足"); // 气球提示await msg.ShowAsync("操作成功完成"); // 简单提示var result = await msg.ShowCheckAsync("确认删除吗?"); // 确认对话框}/// <summary>/// 获取时间/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Button_GetTimeClick(object sender, RoutedEventArgs e){//var time = GetDateTime();}[DllImport("kernel32.dll")]private static extern bool SetLocalTime(ref Systemtime time);[StructLayout(LayoutKind.Sequential)]private struct Systemtime{public short year;public short month;public short dayOfWeek;public short day;public short hour;public short minute;public short second;public short milliseconds;}/// <summary>/// 设置系统时间/// </summary>/// <param name="dt">需要设置的时间</param>/// <returns>返回系统时间设置状态,true为成功,false为失败</returns>public static bool SetLocalDateTime(DateTime dt){Systemtime st;st.year = (short)dt.Year;st.month = (short)dt.Month;st.dayOfWeek = (short)dt.DayOfWeek;st.day = (short)dt.Day;st.hour = (short)dt.Hour;st.minute = (short)dt.Minute;st.second = (short)dt.Second;st.milliseconds = (short)dt.Millisecond;bool rt = SetLocalTime(ref st);return rt;}public static DateTime GetDateTime(long timeStamp){return new DateTime(1970, 1, 1).AddSeconds(timeStamp).ToLocalTime();}public static bool GetInternetTime(string url, out DateTime dt, out string errMsg){dt = DateTime.MinValue;var startDt = DateTime.Now;var port = 13;var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { ReceiveTimeout = 2000 };try{var iphostinfo = Dns.GetHostEntry(url);var ip = iphostinfo.AddressList[0];var ipe = new IPEndPoint(ip, port);var iar = socket.BeginConnect(ipe, null, null);if (!iar.AsyncWaitHandle.WaitOne(5000)){errMsg = "连接超时" + url;return false;}var recvBuffer = new byte[1024];var sb = new StringBuilder();var myE = Encoding.UTF8;int nBytes;while ((nBytes = socket.Receive(recvBuffer, 0, 1024, SocketFlags.None)) > 0){sb.Append(myE.GetString(recvBuffer, 0, nBytes));}var o = sb.ToString().Split(' ');TimeSpan ts = DateTime.Now - startDt;var setDt = Convert.ToDateTime(o[1] + " " + o[2]).Subtract(-ts); // 减去中途消耗的时间dt = setDt.ToLocalTime();Console.WriteLine(@"服务器:{0}时间:{1}", url, setDt);errMsg = "";return true;}catch (Exception ex){errMsg = ex.Message;return false;}finally{socket.Close();}}}
报错内容
FileNotFoundException: 未能加载文件或程序集“Microsoft.Xaml.Behaviors, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依赖项。系统找不到指定的文件。
System.Windows.Markup.XamlParseException:““对类型“gTools.ViewTests.MainWindow”的构造函数执行符合指定的绑定约束的调用时引发了异常。”,行号为“8”,行位置为“5”。”
解决方法:
当然可以不使用它!这个问题的本质是 MahApps.Metro 依赖 Microsoft.Xaml.Behaviors
,但你的项目里没有安装它。
你有两个选择:
- 【推荐】解决依赖问题:安装缺失的 NuGet 包,一劳永逸。这是最简单、最标准的做法。
- 【不推荐】移除依赖源:找到并移除 MahApps.Metro 中使用了
Behaviors
的功能,但这会破坏 UI 库的完整性,得不偿失。
下面我将详细解释这两种方法,并重点说明为什么推荐第一种。
方法一:【推荐】安装缺失的 NuGet 包
这就像汽车需要汽油才能跑一样。你的 UI 库(MahApps.Metro)需要 Microsoft.Xaml.Behaviors
这个“零件”才能正常工作。我们只需要把这个零件给它装上就行了。
操作步骤(非常简单):
- 在 Visual Studio 中,右键点击你的项目(
gTools.ViewTests
),选择 “管理 NuGet 程序包…”。 - 切换到 “浏览” 选项卡。
- 搜索
Microsoft.Xaml.Behaviors
。 - 点击 “安装”。
安装完成后,重新运行项目,问题就解决了。
为什么这是最好的方法?
- 简单快捷:只需要点几下鼠标,无需修改任何代码。
- 官方标准:这是 .NET 生态管理依赖的标准方式。
- 功能完整:你可以继续使用 MahApps.Metro 的所有功能,不会有任何缺失。
- 面向未来:以后升级 MahApps.Metro 或其他库,也不容易出现类似问题。
方法二:【不推荐】尝试不使用它(并解释为什么不可行)
如果你坚持不想安装这个包,理论上就需要找到 MahApps.Metro 中哪个地方用到了它,然后禁用或修改它。但这几乎是不可能的,原因如下:
- 依赖是内部的:
Behaviors
的使用是在 MahApps.Metro 的内部代码里,而不是在你的 XAML 或 C# 代码里。你无法通过修改自己的代码来避开它。 - 破坏库的完整性:
Behaviors
通常用于实现一些复杂的交互效果,比如窗口拖拽、控件动画等。如果你强行移除依赖,可能会导致 MahApps.Metro 的某些核心功能直接崩溃或表现异常。 - 维护噩梦:即使你通过修改 MahApps.Metro 源码的方式成功了(这非常复杂),那么以后每次 MahApps.Metro 更新,你都需要重新修改一遍,这将是一场灾难。
一个形象的比喻:
你买了一个需要安装电池的遥控器,但发现盒子里没有电池。现在遥控器用不了。
- 方法一(推荐):花几块钱买一节电池装上,遥控器就能正常用了。
- 方法二(不推荐):尝试拆开遥控器,修改它的内部电路,让它不依赖电池也能工作。这不仅需要极高的电子技术,而且很可能把遥控器彻底搞坏。
结论与最终建议
请选择方法一,安装 Microsoft.Xaml.Behaviors
NuGet 包。
这并不是一个“可选”的组件,而是 MahApps.Metro 正常工作的一个必需品。你的项目缺少它,就像汽车没有油一样。安装它是解决这个问题的正确、唯一且最简单的途径。
不要因为一个看似“额外”的依赖而放弃使用一个强大的 UI 框架,或者走上修改源码的弯路。安装 NuGet 包是每个 .NET 开发者的日常操作,放心去做吧!