1

Hie. I've currently got an attached property I use to get information from TextBoxes and alter it if need be. However it only works wit textBoxes meaning that user control elements such as ComboBoxes and DatePickers cannot be used with it. I'm not entirely sure where to alter it to get it to work with them too. Here's the class below.

public class TextBoxProperties
{
    public static readonly DependencyProperty IsTextFormattedProperty = DependencyProperty.RegisterAttached("IsTextFormatted", typeof(bool), typeof(TextBoxProperties ), new UIPropertyMetadata(default(bool), OnIsTextFormattedChanged));

    public static bool GetIsTextFormatted(DependencyObject dependencyObject)
    {
        return (bool)dependencyObject.GetValue(IsTextFormattedProperty);
    }

    public static void SetIsTextFormatted(DependencyObject dependencyObject, bool value)
    {
        dependencyObject.SetValue(IsTextFormattedProperty, value);
    }

    public static void OnIsTextFormattedChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        TextBox textBox = dependencyObject as TextBox;
        ComboBox comboBox = dependencyObject as ComboBox;

        // This will work fine...
        if (textBox.Name == "firstNameTextBox")
        {
            bool newIsTextFormattedValue = (bool)dependencyPropertyChangedEventArgs.NewValue;
            if (newIsTextFormattedValue) textBox.TextChanged += MyTextBoxChangedHandler;
            else textBox.TextChanged -= MyTextBoxChangedHandler;
        }

        // This on the other hand will not
        if (comboBox.Name == "genderTextBox")
        {
            bool newIsTextFormattedValue = (bool)dependencyPropertyChangedEventArgs.NewValue;
            if (newIsTextFormattedValue) textBox.TextChanged += MyComboBoxChangedHandler;
            else textBox.TextChanged -= MyComboBoxChangedHandler;
        }
    }

    public static void MyTextBoxChangedHandler(object sender, TextChangedEventArgs e)
    {
        // Do what ever needs to be done with text...
    }

    public static void MyComboBoxChangedHandler(object sender, TextChangedEventArgs e)
    {
        // Do what ever needs to be done with text...
    }

When using it I simply place this in the view's xaml:

<TextBox TextBoxProperties:IsFormatted="True" ... />
<ComboBox TextBoxProperties:IsFormatted="True" ... />

How ever When ever I add the Attached Property to a comboBox, I get the "Object reference not set to an instance of a object" error in the error window. If I run my app, it simply crashes with a first chance exception showing the same message.

Any clue on how to make it work?

Offer
  • 630
  • 2
  • 11
  • 28
  • if(comboBox != null) and [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Mark Nov 03 '14 at 10:04
  • @Offer how can one object be both `ComboBox` and `TextBox`? You should check if `textBox` or `comboBox` are not null and if `comboBox` is not null then `textBox` will be – dkozl Nov 03 '14 at 10:05
  • the argument `dependencyObject` can only be of one Type, so you have to check the type first, if casting using `as`, be sure the result is not null. – King King Nov 03 '14 at 10:05
  • To use `TextChanged` event you can cast `dependencyObject` as `Control`, then you can check type of control in the event handler itself. Your `Name` check is redundant, only assign attached property to a control which will be used with it. After using `as` always check for `null`, especially if you *know* what it will be different types, otherwise use `Control control = (Control)dependencyObject;` (this assumes what you **only** attach property to control, never to something what is not `Control`). – Sinatr Nov 03 '14 at 10:32
  • @Offer what do you want to achieve for `ComboBox`? What should happen when `IsFormatted` is true for `ComboBox`? – dkozl Nov 03 '14 at 10:41
  • @dkozl -Thanks for that. Made a lot of sense actually. I don't intend on doing anything complicated. If IsFormatted is true then the text value in my ComboBox is simply meant to be copied to a string. One I can use in other VMs. I've already used the databinding property to get details from a collectionView so this seemed to be the next best thing. – Offer Nov 03 '14 at 10:53

1 Answers1

2

You should check if textbo is null, as well as combobox:

TextBox textBox = dependencyObject as TextBox;
    ComboBox comboBox = dependencyObject as ComboBox;

    if (textBox != null && textBox.Name == "firstNameTextBox")
    {
        bool newIsTextFormattedValue = (bool)dependencyPropertyChangedEventArgs.NewValue;
        if (newIsTextFormattedValue) textBox.TextChanged += MyTextChangedHandler;
        else textBox.TextChanged -= MyTextChangedHandler;
    }

    if (comboBox != null && comboBox.Name == "genderTextBox")
    {
        bool newIsTextFormattedValue = (bool)dependencyPropertyChangedEventArgs.NewValue;
        if (newIsTextFormattedValue) comboBox.SomeEvent += MyComboBoxChangedHandler;
        else comboBox.SomeEvent -= MyComboBoxChangedHandler;
    }
ShayD
  • 920
  • 8
  • 18
  • it will still cause null reference exception because if it's `ComboBox` then `textBox`, which you refer to in second if, will be null. It cannot be both `ComboBox` and `TextBox` – dkozl Nov 03 '14 at 10:09
  • this should not cause null reference exception, each is checked for null before accessing it. – ShayD Nov 03 '14 at 10:11
  • It will. Second if, when `ComboBox`, does `textBox.TextChanged += MyComboBoxChangedHandler` or `textBox.TextChanged -= MyComboBoxChangedHandler` and `textBox` in this case will be null – dkozl Nov 03 '14 at 10:13