4

Suppose I had a TextBox control, and I wanted to add a simple string property to it without having to create a new Textbox control which inherits from the regular TextBox control. Is that possible?

For example, something like:

TextBox tx = new TextBox();
// I want something like the following
// tx.addProperty("propertyname", "properyvalue", typeof(string));

Is there such thing in WPF/C#, and what is the simplest way to do this without having to create a new Textbox control which inherits from the regular TextBox control?

Stephen Hewlett
  • 2,415
  • 1
  • 18
  • 31
user1590636
  • 1,174
  • 6
  • 26
  • 56
  • 2
    Do you know you can use Tag Property for storing any value with each control? for example tx.Tag = "some text" – Mohamed Salemyan Aug 24 '13 at 15:50
  • Any particular reason why you specifically *don't* want to use the most simple and easy way and just make a subclass of texbox? – Corak Aug 24 '13 at 15:50

2 Answers2

5

You can create a attached dependency property, and apply it to any type of control. For example, for TextBlock. Below is my example:

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>

Code behind

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);
    }
}

Or you can use a property Tag, it just has been created to store additional information. But sometimes, this property can be occupied by other objectives, or may not hold because of his name. Far better to create their property with an intuitive name, for example: ValueForAnimation, StringId, CanScrolling, etc.

Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
  • 1
    I don't see any `MyProperty` declared in the class `MyDependencyClass` as in the XAML code `MyDependencyClass.MyProperty`? Shouldn't it be `MyDependencyClass.MyPropertyForTextBlockProperty`? – King King Aug 24 '13 at 16:07
  • @King King: Yes, I'm in a hurry and forgot to rename Get and Set, I'll fix it. Thank you for your attention. – Anatoliy Nikolaev Aug 24 '13 at 16:12
4

In general, the best way to do this is to inherit from the TextBox control. Unlike javascript, C# is a statically typed language so you can't just add properties like that.

As the Textbox control is a DependencyObject you are able to use attached properties too - see Anatoliy Nikolaev's answer above/below for that. This may be better depending on how you want to use the property.

If you just want to add a single piece of information, you could use the Tag property of the Textbox, which is designed for this purpose and can take any object. If you want to add more than one piece of information, you could set the Tag property to a dictionary of values.

Community
  • 1
  • 1
Stephen Hewlett
  • 2,415
  • 1
  • 18
  • 31