WPF依赖属性:自动转换GetValue()返回类型与简化重复代码的方案咨询
(编辑说明):我之前犯了个错,没给问题搭配更简单的示例来聚焦依赖属性代码重复冗余的问题——
LabeledConainer和LabeledTextBox其实是次要的,核心问题在依赖属性上。
我现在在WPF和C#/.NET环境下开发,正在用依赖属性构建一些基础控件。我想把这类代码的模式变得尽可能可复用、易维护,比如复制粘贴一个依赖属性后,只需要修改少量内容就能生成新属性。
我做了一个带附加标签的TextBox,放在DockPanel里。LabeledContainer是个通用控件,包含了标签和控件在DockPanel中的所有逻辑,还能快速指定标签显示在控件的左、右、上、下位置——这些功能都正常工作,而且和当前问题无关。
下面是精简后的示例代码:
namespace MyApp.Controls { using ContentType = TextBox; using MyType = LabeledTextBox; public partial class LabeledTextBox : LabeledContainer { public new ContentType Content { get { return base.Content as ContentType; } set { base.Content = value; } } public static readonly DependencyProperty SetTextBoxTextProperty = DependencyProperty.Register( nameof(TextBoxText), typeof(string), typeof(MyType)); public string TextBoxText { get { return (string)GetValue(SetTextBoxTextProperty); } set { SetValue(SetTextBoxTextProperty, value); } } } public LabeledLabel() : base() { InitializeComponent(); } }
我的问题出在这行的(string)强制转换上:
get { return (string)GetValue(SetTextBoxTextProperty); }
倒不是会报错,而是每次复制粘贴这段代码来创建新的依赖属性时(比如要暴露TextBox的HorizontalAlignment这类属性,我现在经常做这种事),都得修改这个转换类型。
有没有什么泛型逻辑能自动把GetValue()的返回值转换成属性的目标类型?毕竟属性的类型已经明确了,有没有语法能引用当前属性的返回类型?最好是编译时就能解析的方案,完全不影响性能,不过其他方案我也愿意看看。
更宽泛地说,这是我目前总结的基础依赖属性模式(注意我用了MyType来把属性注册的代码浓缩到一行)。我好奇这种模式是不是有什么不足之处,或者有没有其他方法能解决我的问题、进一步减少重复代码——会不会我现在的思路根本就不对?
我平时偶尔会写Rust代码,想到Rust里的宏是解决这类重复代码的绝佳方案,但我不太清楚C#里有没有类似的工具。
(补充编辑):把示例代码里的
ContentType别名从Label改成了TextBox,之前整理示例时写错了。
备注:内容来源于stack exchange,提问作者lejero

