MahApps.Metro WPF 开发使用过程中遇到的问题 - 未能加载文件或程序集“Microsoft.Xaml.Behaviors,

MahApps.Metro WPF 开发使用过程中遇到的问题

MainWindow.xaml

代码不是测试重点 重点是使用了 MahApps.Metro

csharp 复制代码
<mah:MetroWindow
    x: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>
        <UniformGrid
            Margin="5"
            Columns="9"
            Rows="9">
            <!--  手动添加81个按钮(实际开发建议用代码生成)  -->
            <Button
                Margin="2"
                Click="Button_MessageClick"
                Content="弹窗测试" />
            <Button
                Margin="2"
                Click="Button_GetTimeClick"
                Content="获取时间" />
            <!--  省略其他79个按钮...  -->
            <Button Margin="2" Content="9-9" />
        </UniformGrid>
    </Grid>
</mah:MetroWindow>

MainWindow.xaml.cs

csharp 复制代码
    /// <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,但你的项目里没有安装它 。

你有两个选择:

  1. 【推荐】解决依赖问题:安装缺失的 NuGet 包,一劳永逸。这是最简单、最标准的做法。
  2. 【不推荐】移除依赖源 :找到并移除 MahApps.Metro 中使用了 Behaviors 的功能,但这会破坏 UI 库的完整性,得不偿失。
    下面我将详细解释这两种方法,并重点说明为什么推荐第一种。

方法一:【推荐】安装缺失的 NuGet 包

这就像汽车需要汽油才能跑一样。你的 UI 库(MahApps.Metro)需要 Microsoft.Xaml.Behaviors 这个"零件"才能正常工作。我们只需要把这个零件给它装上就行了。
操作步骤(非常简单):

  1. 在 Visual Studio 中,右键点击你的项目(gTools.ViewTests),选择 "管理 NuGet 程序包..."。
  2. 切换到 "浏览" 选项卡。
  3. 搜索 Microsoft.Xaml.Behaviors。
  4. 点击 "安装" 。
    安装完成后,重新运行项目,问题就解决了。
    为什么这是最好的方法?
  • 简单快捷:只需要点几下鼠标,无需修改任何代码。
  • 官方标准:这是 .NET 生态管理依赖的标准方式。
  • 功能完整:你可以继续使用 MahApps.Metro 的所有功能,不会有任何缺失。
  • 面向未来:以后升级 MahApps.Metro 或其他库,也不容易出现类似问题。

方法二:【不推荐】尝试不使用它(并解释为什么不可行)

如果你坚持不想安装这个包,理论上就需要找到 MahApps.Metro 中哪个地方用到了它,然后禁用或修改它。但这几乎是不可能的,原因如下:

  1. 依赖是内部的 :Behaviors 的使用是在 MahApps.Metro 的内部代码里,而不是在你的 XAML 或 C# 代码里。你无法通过修改自己的代码来避开它。
  2. 破坏库的完整性 :Behaviors 通常用于实现一些复杂的交互效果,比如窗口拖拽、控件动画等。如果你强行移除依赖,可能会导致 MahApps.Metro 的某些核心功能直接崩溃或表现异常。
  3. 维护噩梦 :即使你通过修改 MahApps.Metro 源码的方式成功了(这非常复杂),那么以后每次 MahApps.Metro 更新,你都需要重新修改一遍,这将是一场灾难。
    一个形象的比喻:
    你买了一个需要安装电池的遥控器,但发现盒子里没有电池。现在遥控器用不了。
  • 方法一(推荐):花几块钱买一节电池装上,遥控器就能正常用了。
  • 方法二(不推荐):尝试拆开遥控器,修改它的内部电路,让它不依赖电池也能工作。这不仅需要极高的电子技术,而且很可能把遥控器彻底搞坏。

结论与最终建议

请选择方法一,安装 Microsoft.Xaml.Behaviors NuGet 包。

这并不是一个"可选"的组件,而是 MahApps.Metro 正常工作的一个必需品 。你的项目缺少它,就像汽车没有油一样。安装它是解决这个问题的正确、唯一且最简单的途径。

不要因为一个看似"额外"的依赖而放弃使用一个强大的 UI 框架,或者走上修改源码的弯路。安装 NuGet 包是每个 .NET 开发者的日常操作,放心去做吧!


相关推荐
编码者卢布4 小时前
【Azure Container Apps】为什么通过 Diagnostic Settings 发送到 Log Analytics 中的日志会延迟几分钟?
microsoft·azure
0x00076 小时前
微软intelligent-terminal:Windows 的官方内置Agent Cli
microsoft
海盗12347 小时前
微软技术日报 2026-11-02:开发者环境服务退役、Defender 清点本地 AI 代理
人工智能·microsoft·机器人·人工智能aigc
海盗12341 天前
微软技术日报 2026-11-01:语言模型 API 免申请、8 个威胁组织被分四档
人工智能·microsoft·语言模型·机器人·人工智能aigc
ShineWinsu2 天前
对于Qt:QRadioButton常见属性以及QButtonGroup的解析
数据库·c++·qt·microsoft·gui·qradiobutton·qbuttongroup
鬼手点金2 天前
提示注入:上下文安全的核心威胁
人工智能·安全·microsoft·机器学习·缓存·prompt
avi91112 天前
电影开源Jevdo - 源码介绍(vue版)没有android 和 没有wpf
android·wpf·框架·数据爬虫·meego·电影管理
JSMSEMI112 天前
JSM20NP06D N 沟道 + P 沟道互补对管 MOSFET
microsoft
前端精髓3 天前
调用大模型API
运维·服务器·microsoft
老牛日常随笔3 天前
微软开源Flint Chart:AI画图表总是画不对?让编译器来画,AI只写数据就行
人工智能·microsoft