重写 WPF 控件

2023-12-10

我有一个来自第三方的 WPF 控件 ParentWPFControl,我想继承该控件(我们将其称为子类 ChildWPFControl)。在这个过程中,我计划重写一些后端逻辑和部分前端样式。前者我可以做得很好,但后者我有问题。

我尝试对子国家/地区使用 xaml xaml.cs 结构,但这似乎是不允许的,并且 VS 发出以下警告:

Partial declarations of 'ChildWPFControl' must not specify different base classes

现在,我想我可以编写一个 ResourceDictionary XAML 并在那里定义前端,但如果我想向 XAML 添加事件处理程序,这就会成为一个问题(至少我找不到方法来做到这一点)

我的另一种选择是直接在使用 ChildWPFControl 的对象中定义覆盖模板,但这会降低设计的模块化程度。

我能想到的最后一个替代方案是创建一个 xaml xaml.cs 对,它是一个 XAML 样式容器,然后强制 ChildWPFControl 使用通过后端事件处理程序定义的 ControlTemplate。

不管怎样,我正在寻找一个优雅且模块化的解决方案来解决我的问题。任何建议都会受到欢迎。

Thanks


完全重写 WPF 控件需要执行几个步骤。有些是必需的,有些是可选的,具体取决于您的需要。我将向您解释两个重要的内容:

创建新的默认样式

每个 WPF 控件都有一个默认样式,其中包含其视觉表示和覆盖属性。现在,如果您从控件派生 WPF 仍然认为您想要使用此默认样式,则可以在静态构造函数中更改 DefaultStyle,如下所示

class MyButton : Button
{
    static MyButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
    }
}

现在,如果您使用 MyButton,WPF 会尝试为 MyButton 而不是 Button 查找样式。 OverridesDefaultStyle 是样式中的一个属性,在某些时候也可能很方便。通常这些默认样式应该放置在主题相关的 xaml 中。

覆盖类时的事件处理程序

这是正确的ControlTemplate or Style你不能使用使用事件的语法糖,例如Click="OnClick"。关键是,视觉表示尽可能地与逻辑部分解耦。还有其他方法可以克服这个问题,即使用 OnApplyTemplate 方法。通过覆盖它,您可以询问模板“给我这个控件”,然后您只需在其中添加事件即可。

override OnApplyTemplate()
{
    var innerChild = Template.FindName("PART_InnerChild", this) as MyInnerControl;
    if(innerChild != null)
        innerChild.SomeEvent += OnSomeEvent;
}

注意:按照惯例,这些控件的名称通常以 PART_ 开头,这也可以在 WPF 基本控件中看到。这是告诉设计者“如果没有这个控制,逻辑部分可能会崩溃”的好方法。还有一个属性模板部分但这并不重要,WPF 并不关心它。据我所知,Expression Blend 对此做了一些工作,我个人用它来告诉其他人什么样的内部控件对于使该控件工作是绝对必要的。

个人建议

从类派生通常是我们尝试自定义控件时所做的最后一步。因为要完全使其工作需要做很多工作,并且它可能会限制可重用性,所以我们尽量避免它,例如,除了模板覆盖和样式之外,还有一个好的替代方案;依附行为.

最后, 整个主题涵盖在不错的MSDN文章。

希望有帮助

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

重写 WPF 控件 的相关文章

随机推荐

  • 在您自己的软件中使用 VBA

    我想在我的软件中使用 Visual Basic 我想知道它是否受版权保护 任何线索将不胜感激 谢谢 VBScript 很容易嵌入 VBA 需要许可证 这是添加 VBScript 作为宏语言的 VB6 VBA 代码 With ScriptCo
  • 如何从 vmware_guest_disk_facts 获取字典条目

    我正在尝试获取特定硬盘的数据存储名称 但我未能成功地找出列表中的选择条目 此输出来自 ansible 模块 vmware guest disk facts 我将此输出保存到名为 vm info 的变量中 guest disk facts 0
  • java.lang.Throwable:setStateLocked

    每次从其他 Activity 意图到 LoginActivity 时 都会使应用程序崩溃 错误的Logcat AccessibilityManager setStateLocked wasEnabled false mIsEnabled 假
  • 将文本字符串转换为电子表格中的公式

    我正在尝试开发一个交互式电子表格 为预算文件创建叙述 将会有多种选择 一旦用户选择了一个项目 它将帮助他们计算总数 我想设置它们填写的选项框 例如 将允许输入 B1 B4 四个单元格 我将为四个单元格分别命名 即 A B C D 在参考文档
  • 将整数数组映射到嵌套数组访问

    有没有一种方法可以使用本身存储在数组中的索引来动态访问嵌套数组 主数组 矩阵嵌套可以是可变的 例如2 4 100 Example my array 1 2 3 4 5 6 7 8 9 10 11 12 my array access usi
  • LESS 无声多行注释

    有没有办法创建silentLESS 中的多行注释 我想要与 comment 相同的行为 但对于多行字符串 正如 harry 已经明确指出的 x and clean css选项也会删除评论 从版本 2 开始 clean css 选项已移至插件
  • 如何在 JavaScript 中使用 toLocaleString() 和 tofixed(2)

    我怎样才能在 JavaScript 中做到这一点 var num 2046430 num toLocaleString will give you 2 046 430 我尝试过的是 var num 2046430 num toLocaleS
  • 带有 MAX(n.property) 的 Cypher 返回节点

    With Cypher 我试图返回得分最高的节点 然而 它要么只返回分数 而没有任何 id 到节点 我需要在查询中添加什么 start n node WHERE HAS n score return MAX n score 该解决方案应该为
  • 找不到 Oracle jdbc 驱动程序

    我对 java 和数据库连接很陌生 我正在尝试与 Oracle 数据库建立一个非常简单的连接 当我运行这段代码时 import java sql import oracle jdbc pool OracleDataSource public
  • Nodejs 上的 Javascript ES6:类型错误:对象不是构造函数

    我有这个样本班sync js作为我项目中某处的模块 use strict export default class Sync constructor dbConnection this dbConnection dbConnection t
  • jquery validator - 仅验证可见元素

    我有一个隐藏 显示 div 的单选按钮 所有可见元素都是 必需的 但是在验证规则之后添加ignore hidden 不起作用 这是代码
  • 将序列划分为唯一对的集合

    我需要一个 of 函数 它可以将序列分成对 然后将它们组合起来 以便组合中的所有元素都是唯一的 我已经尝试了多种使用 python 的 itertools 的方法 但还没有找到解决方案 为了说明这一点 我想要一个采用以下序列的函数 1 2
  • 使用 UserDefaults 保存图像数组

    我有一个应用程序 用户可以在其中拍照 拍照后应将其保存到UserDefaults 我不断收到此错误 cannot invoke setObject with an argument list of type UIImage type for
  • 如何获取android上每个cpu核心的使用情况

    我在 Android 上开发了一个小部件 它显示许多有用的信息 我正在尝试修改此方法以返回一个 cpu 核心的使用百分比 以便获得每个核心的使用百分比 在我的 HTC One X 上 我在 proc stat 中有 cpu 183549 1
  • 如何将 scikit-learn 数据集写入 csv 文件

    我可以从以下位置加载数据集scikit learn using from sklearn import datasets data datasets load boston print data 我想做的是将这个数据集写入一个平面文件 cs
  • 无法对实体框架 6 使用 MySQL 连接

    我正在尝试将实体框架 6 与 MySQL 一起使用 我确实为 Visual Studio 1 1 1 和 MySQL Net 连接器 6 8 3 安装了 MySQL 插件 问题是当我尝试创建新的 ADO NET 实体模型时 我无法选择 My
  • 为什么我不能在此三元运算中将 int 转换为字符串

    为了简洁起见 我留下了一些代码 int id Convert ToInt32 Page RouteData Values id var q db Categories SingleOrDefault x gt x categoryID id
  • Android 地点选择器启动后立即关闭

    我正在开发一个android应用程序作为项目的一部分 并使用Google地方API来根据位置显示感兴趣的地方 我正在使用 PlacePicker Inentbuilder 来完成此任务 但是 当应用程序运行时 地点选择器会启动 然后立即关闭
  • 在 WPF 应用程序中嵌入 Unity3D 应用程序

    我想在 WPF 中开发一个新的 CAD 软件 而不是使用 WPF 3D 是否可以使用 Unity3D 作为我的图形引擎 能够根据 WPF 中的数据对象旋转 平移 缩放和查看 3D 图形对象 我问这个问题的原因是 Unity 是一个游戏引擎
  • 重写 WPF 控件

    我有一个来自第三方的 WPF 控件 ParentWPFControl 我想继承该控件 我们将其称为子类 ChildWPFControl 在这个过程中 我计划重写一些后端逻辑和部分前端样式 前者我可以做得很好 但后者我有问题 我尝试对子国家