如何向现有类型/控件添加属性

4
假设我有一个TextBox控件,并且想要添加一个简单的字符串属性到它,而不必创建一个继承自常规TextBox控件的新TextBox控件。这是否可能?
例如,像这样:
TextBox tx = new TextBox();
// I want something like the following
// tx.addProperty("propertyname", "properyvalue", typeof(string));

在WPF/C#中,是否有这样的东西?如果不想创建一个继承自常规TextBox控件的新TextBox控件,最简单的方法是什么?

2
你知道吗?你可以使用标签属性为每个控件存储任何值。例如:tx.Tag = "一些文本" - Mohamed Salemyan
有什么特别的原因,让你不想使用最简单、最容易的方法,而是要创建一个文本框的子类呢? - Corak
2个回答

5
你可以创建一个附加依赖属性,并将其应用于任何类型的控件。例如,对于TextBlock。以下是我的示例:

XAML

<Grid>
    <TextBlock Name="SampleTextBlock" Width="200" Height="30" 
               Background="AntiqueWhite" Text="Sample TextBlock" 
               local:MyDependencyClass.MyPropertyForTextBlock="TestString" />

    <StackPanel Width="100" Height="100" HorizontalAlignment="Left">
        <Button Name="GetValueButton" Content="GetValueButton" Click="GetValue_Click" />
        <Button Name="SetValueButton" Content="SetValueButton" Click="SetValue_Click" />
    </StackPanel>
</Grid>

代码后端

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void GetValue_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(MyDependencyClass.GetMyPropertyForTextBlock(SampleTextBlock));
    }

    private void SetValue_Click(object sender, RoutedEventArgs e)
    {
        MyDependencyClass.SetMyPropertyForTextBlock(SampleTextBlock, "New Value");

        MessageBox.Show(MyDependencyClass.GetMyPropertyForTextBlock(SampleTextBlock));
    }
}

public class MyDependencyClass : DependencyObject
{
    public static readonly DependencyProperty MyPropertyForTextBlockProperty;

    public static void SetMyPropertyForTextBlock(DependencyObject DepObject, string value)
    {
        DepObject.SetValue(MyPropertyForTextBlockProperty, value);
    }

    public static string GetMyPropertyForTextBlock(DependencyObject DepObject)
    {
        return (string)DepObject.GetValue(MyPropertyForTextBlockProperty);
    }

    static MyDependencyClass()
    {
        PropertyMetadata MyPropertyMetadata = new PropertyMetadata(string.Empty);

        MyPropertyForTextBlockProperty = DependencyProperty.RegisterAttached("MyPropertyForTextBlock",
                                                            typeof(string),
                                                            typeof(MyDependencyClass),
                                                            MyPropertyMetadata);
    }
}

或者您可以使用属性Tag,它只是被创建用来存储额外的信息。但有时,这个属性可能会被其他目标占用,或者因为名称而不适用。更好的方法是创建一个具有直观名称的属性,例如:ValueForAnimationStringIdCanScrolling等。


1
在XAML代码中,我没有看到类MyDependencyClass中声明任何MyProperty。难道不应该是MyDependencyClass.MyPropertyForTextBlockProperty吗? - King King
@King King:是的,我很匆忙,忘记重命名Get和Set了,我会修复它的。谢谢你的关注。 - Anatoliy Nikolaev

4
一般来说,最好的方法是继承TextBox控件。与javascript不同,C#是一种静态类型语言,因此无法直接添加属性。
由于Textbox控件是DependencyObject,您也可以使用附加属性-请参见Anatoliy Nikolaev的答案以获取更多信息。根据您想要使用该属性的方式,这可能更好。
如果您只想添加单个信息,则可以使用Textbox的Tag属性,该属性专为此目的设计,可以接受任何对象。如果您想添加多个信息,则可以将Tag属性设置为值字典。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接