PauLEffect
PauLEffect

Reputation: 423

Wpf binding Clarification (beginner)

I'm new to wpf, as the title suggests. I was using wpf as it was winforms (what's all that binding non sense anyway) until, of course, I tried it and got blown away.

So I was digging into user controls and dependency properties. I read that, in order to get the ui to remain in sync with what's under the hood you need to use observable collections, notifypropertychanged / changing and dependency properties for the stuff that you use.

My question is this:

Let's say I have this dep. prop. for a user control (type of Media.Color) :

public Color Color
{
    get { return (Color)GetValue(ColorProperty); }
    set { SetValue(ColorProperty, value); }
}

The xaml uses it for a binding, it works, all is good. But, when it gets updated, I would like to do something with it in code.

So I tried putting a Console.writeline("fired") like so:

public Color Color
{
    get { return (Color)GetValue(ColorProperty); }
    set { 
            Console.WriteLine("Fired"); 
            SetValue(ColorProperty, value); 
        }
}   

No dice. Could someone please enlighten me how this stuff works? I am obviously missing something (just the other day someone on stack told me about MouseCapture so... ).

Thank you for your time.

Edit

http://www.wpftutorial.net/DependencyProperties.html

Basically it says, in big bold letters,

Important: Do not add any logic to these properties, because they are only called when you set the property from code. If you set the property from XAML the SetValue() method is called directly.

If you are using Visual Studio, you can type propdp and hit 2x tab to create a dependency property.

And goes on to explain why and how you should proceed.

Solution

So, I tried what @Krishna suggested, and my user control crashed and burned.

Here was my dep prop. (as it was before asking this question).

public static readonly DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(ColorPickerMaster), new PropertyMetadata(default(Color)));

Turns out the problem was using (...) new Prop.Metadata(null, OnPropChanged)

Using

public static readonly DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(ColorPickerMaster), new PropertyMetadata(OnColorChanged));

private static void OnColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    Console.WriteLine(e.NewValue);
}

yields a beautiful win.

Thank you for your time and answers.

Upvotes: 0

Views: 85

Answers (2)

Krishna
Krishna

Reputation: 1996

When it comes to DependencyProperties you use property changed callback to track changes to your property like below example. And then you use e.NewValue and e.OldValue to write your logic. More about DependencyProperties on MSDN

public Color color
        {
            get { return (Color)GetValue(colorProperty); }
            set { SetValue(colorProperty, value); }
        }
        public static readonly DependencyProperty colorProperty =
            DependencyProperty.Register("color", typeof(Color), typeof(YourClass), new PropertyMetadata(null,colorChanged));

        private static void colorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            YourClass c = d as YourClass;
            if(c!=null)
            {

            }
        }

Upvotes: 1

Novitchi S
Novitchi S

Reputation: 3741

From MSDN - XAML Loading and Dependency Properties:

The current WPF implementation of its XAML processor is inherently dependency property aware. The WPF XAML processor uses property system methods for dependency properties when loading binary XAML and processing attributes that are dependency properties. This effectively bypasses the property wrappers. When you implement custom dependency properties, you must account for this behavior and should avoid placing any other code in your property wrapper other than the property system methods GetValue and SetValue.

If you want to add custom logic in a setter you will have to make it a simple field (not a DependecyProperty) implement INotifyPropertyChanged and bind to it.

Upvotes: 1

Related Questions