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 开发者的日常操作,放心去做吧!


相关推荐
FreeBuf_6 小时前
安全补丁还是自造DDoS?微软更新导致关键企业功能瘫痪
microsoft·ddos
△曉風殘月〆16 小时前
WPF中的坐标转换
wpf
一个帅气昵称啊19 小时前
使用微软Agent Framework .NET构建智能代理应用
microsoft·flask·.net
一个天蝎座 白勺 程序猿20 小时前
深度解析:通过ADO.NET驱动Kdbndp高效连接与操作Kingbase数据库
数据库·.net·wpf·kingbase·金仓数据库
时光追逐者21 小时前
一个使用 WPF 开发的 Diagram 画板工具(包含流程图FlowChart,思维导图MindEditor)
c#·.net·wpf·流程图
Vae_Mars21 小时前
WPF中的DataTemplate
wpf
Aevget21 小时前
界面控件DevExpress WPF v25.2新功能预览 - 聚焦AI功能提升
人工智能·wpf·界面控件·devexpress·ui开发·.net 10
csdn_aspnet1 天前
如何从 WPF 控件 DataGrid 中删除多余的列
wpf·datagrid
张人玉1 天前
C#WPF如何实现登录页面跳转
ui·c#·wpf