Wpf 将依赖项属性添加到现有.NET类

Wpf 将依赖项属性添加到现有.NET类,wpf,dependency-properties,Wpf,Dependency Properties,在WPF项目中,我有一组控件,我希望能够在其中设置单个Margin属性并保留其他值。因此,我希望避免将完整边距设置为新的厚度(margin=“0,5,0,15”)。因为许多页边距是根据样式等设置的,但在个别情况下,我希望对某些控件偏离通用样式 我想,为什么不像这样在.NET类FrameWorkElement上注册几个新的依赖属性(例如,只显示MarginLeft): 但该属性在代码隐藏或XAML中不可用。我可以理解它,因为这个虚拟类从来没有被实例化过。试图使其成为一个静态类,但无法从FrameW

在WPF项目中,我有一组控件,我希望能够在其中设置单个
Margin
属性并保留其他值。因此,我希望避免将完整边距设置为新的
厚度
margin=“0,5,0,15”
)。因为许多页边距是根据样式等设置的,但在个别情况下,我希望对某些控件偏离通用样式

我想,为什么不像这样在.NET类
FrameWorkElement
上注册几个新的依赖属性(例如,只显示MarginLeft):

但该属性在代码隐藏或XAML中不可用。我可以理解它,因为这个虚拟类从来没有被实例化过。试图使其成为一个静态类,但无法从FrameWorkElement派生(我需要GetValue和SetValue方法使用FrameWorkElement)

我在网上找不到任何资源来处理更一般的问题:你能给现有的.net类添加依赖属性吗

任何帮助/明智的建议都将不胜感激


顺便说一句:仅改变边缘(厚度)的一个组成部分的解决方案也值得赞赏;)

如果您只想更改xaml margin=“1,2,3,4”中边距使用的一个组件,其中1-左、2-上、3-右、4-下

如果您想定义要在您不拥有的对象上设置的属性,那么您想定义附加属性,在这种情况下,您将使用该方法而不是注册。您还可以将该属性定义为静态get/set方法,而不是实例属性,因为它不会在对象的实例上设置,而是在某个未知的frameworkelement上设置。链接中的帮助主题显示了一个示例。其他评论中的链接也提供了更多信息和示例。

您可能想了解一下。尤其是这一部分。为什么没有说明原因就被否决了?这似乎是一个合理的问题。我当然知道……但我希望能够只设置上边距,例如,不影响其他地方样式设置的其他边距(左、右、下)……不……这会使其他边距保持不变吗?对不起,它不起作用…也许它有帮助,我应该把这个附加属性的注册放在哪里,以便从FrameworkElement派生的所有控件都可以使用它?您可以在任何类上定义它-甚至不必是依赖项对象。当然,如果要设置附加属性,必须引用定义该属性的类。So local:FrameworkElementExtensions.MarginLeft=20例如,其中local映射到定义它的clr命名空间(例如,如果它在本地程序集和clr命名空间foo中,则xmlns:local=“clr namespace:foo”)。也就是说,如果您计划在使用附加属性的同时直接设置Margin属性,那么这种方法将不会很好地工作。我的意思是,如果xaml处理器在实际的Margin属性设置之前应用您的属性,该怎么办?您必须观察边距属性何时更改,如果您不是更改的人,则重新插入更改。此外,如果Margin属性上有绑定,您可能会删除/步进绑定(因为您的值将是本地值属性优先级)。您可能可以使用DependsOnAttribute来影响道具的顺序,但我不确定这是否有效。上一次我尝试使用它时,在WPF的早期,它没有起到任何作用。文档表明它会影响XamlWriter.Save的顺序。这不是我需要的,我必须得出结论。我不需要附加属性,这样我就可以执行FrameworkElementExtensions.MarginLeft=20。我希望每个框架元素(及其派生类)都有MarginLeft可用。并像这样使用:btnAdd.MarginLeft=20,txtlab.MarginLeft=15,等等。
public class FrameWorkElementExtensions: FrameworkElement
{
    public static readonly DependencyProperty MarginLeftProperty = DependencyProperty.Register("MarginLeft", typeof(Int16?), typeof(FrameworkElement), new PropertyMetadata(null, OnMarginLeftPropertyChanged));
    public Int16? MarginLeft
    {
        get { return (Int16?)GetValue(MarginLeftProperty); }
        set { SetValue(MarginLeftProperty, value); }
    }

    private static void OnMarginLeftPropertyChanged(object obj, DependencyPropertyChangedEventArgs e)
    {
        if (obj != null && obj is UIElement)
        {
            FrameworkElement element = (FrameworkElement)obj;

            element.Margin = new Thickness((Int16?)e.NewValue ?? 0, element.Margin.Top, element.Margin.Right, element.Margin.Bottom);
        }
    }
}