views:

73

answers:

1

I'm a little confused on creating a DependencyProperty for properties that depend on external sources. For example, in an ultrasound application I'm writing, I currently have the following in a Managed C++ wrapper (translated to C# for simplicity on here, implementing INotifyPropertyChanged):

public int Gain
{
    get { return ultrasound.GetParam(prmGain); }
    set 
    { 
        ultrasound.SetParam(prmGain, value);
        NotifyPropertyChanged("Gain");
    }
}

All my code is used in WPF, and I was considering how changing the INotifyPropertyChanged to DependencyProperty would happen, and if I'd benefit from the changes. There are around 30 variables similar to this one, most of which get databound to an on-screen slider, textblock, or other control.

Would the following be correct for implementing a DependencyProperty for this object?

public int Gain
{
    get { return ultrasound.GetParam(prmGain); }
    set 
    { 
        ultrasound.SetParam(prmGain, value);
        this.SetValue(GainProperty, value); 
    }
}

public static readonly DependencyProperty GainProperty = DependencyProperty.Register(
    "Gain", typeof(int), typeof(MyUltrasoundWrapper), new PropertyMetadata(0));

I've never seen an example where this.GetValue(GainProperty) wasn't used. Also, there are other functions that may change the value. Would this be the correct change as well?

public void LoadSettingsFile(string fileName)
{
    // Load settings...

    // Gain will have changed after new settings are loaded.
    this.SetValue(GainProperty, this.Gain);
    // Used to be NotifyPropertyChanged("Gain");
}

Also, on a side note, should I expect performance gains in cases where most of the properties are databound, or rather, performance loss in cases where many parameters are NOT databound?

+2  A: 

When using a dependency property the Get and Set methods must just be simple wrappers for this.GetValue() and this.SetValue(), the reason for this is that WPF does not use the getters or setters to access the value so you can't depend on the extra code running all the time.

If you do need these properties to be dependency properties then create a standard dependency property which effectively caches your ultrasound.GetParam(prmGain) result and call ultrasound.SetParam(prmGain, value) inside the PropertyChanged event which will reliably be called no matter how the property is changed.


While what I have written above is still correct, rereading you question makes me think that you may be misunderstanding what a dependency property is. If this C++ wrapper object is effectively your model then you want to stay with INotifyPropertyChanged. Dependency properties are designed to be used by a WPF control internally to facilitate binding and lower the control's memory footprint. They aren't supposed to be used inside the data provider, that is what the notification interfaces are for.

Martin Harris
This is the reason i passed in this.Gain (which calls ultrasound.GetParam) when doing SetValue, and value in the case where the value is being manually set. I thought the logic above would always keep an up-to-date local version of Gain.
Will Eddins
I think you may be fine with the getting of the value. My concern is with the setting. When the value is set through a WPF binding it won't call Set therefore ultrasound.SetParam(prmGain, value); won't be called and the value in the ultrasound object won't be updated. The binding doesn't call get or set, it acts directly on the dependency property itself.
Martin Harris
You're probably right that I'm thinking through it too much, I should just keep it as INotifyPropertyChanged. I only have INotifyPropertyChanged implemented as a facility for databinding to WPF so I thought DependencyProperties could speed this up, but the fact that they aren't local variables makes it unnecessarily complex for keeping data in sync.
Will Eddins