WPF窗口自定义基类继承问题:如何阻止自动代码覆盖继承关系
解决WPF窗口自定义基类继承的问题
嘿,这个问题我之前也碰到过!WPF的分部类机制和WinForms不一样,光改cs文件的基类没用,得同步修改XAML文件才行,下面给你一步步解决:
核心解决方案:修改XAML的根元素
WPF自动生成的*.g.i.cs文件是根据XAML里的根节点来生成基类的,所以你需要把登录窗口的XAML文件里的<Window>替换成你的<BaseWindow>,还要加上对应的命名空间引用。
举个例子,你的wndLogin.xaml原来的开头是这样的:
<Window x:Class="MyProject.wndLogin" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Login" Height="300" Width="400">
改成这样:
<local:BaseWindow x:Class="MyProject.wndLogin" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MyProject.Classes" Title="Login" Height="300" Width="400">
这里的xmlns:local="clr-namespace:MyProject.Classes"是引入你的BaseWindow所在的命名空间,确保XAML能找到这个类。
改完之后,你再看自动生成的wndLogin.g.i.cs文件,会发现它已经自动继承BaseWindow了,再也不会被覆盖回System.Windows.Window啦!
额外优化:确保Height/Width获取正确值
还有个小坑要注意:你现在在BaseWindow的构造函数里设置MinHeight = Height,这时候XAML里设置的Height和Width还没加载完成(因为InitializeComponent()是在子类构造函数里调用的,晚于基类构造),所以拿到的可能是默认值,不是你想要的窗口大小。
建议把这段逻辑移到OnInitialized方法里,这样能确保XAML的属性已经被正确加载:
namespace MyProject.Classes { public class BaseWindow : System.Windows.Window { protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); MinHeight = Height; MinWidth = Width; } } }
进阶:自定义窗口模板(可选)
如果以后要新建很多继承BaseWindow的窗口,不想每次都改XAML,可以自定义Visual Studio的窗口模板:
- 找到Visual Studio的WPF窗口模板路径(一般在
Visual Studio安装目录\Common7\IDE\ItemTemplates\CSharp\WPF\1033) - 复制默认的
Window模板文件夹,修改里面的Window.xaml和Window.xaml.cs,把基类换成你的BaseWindow - 重启Visual Studio,以后新建窗口时就能直接选你自定义的模板了
这样就能一劳永逸啦!
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

