2

I have a WPF window with controls I wish to bind to my model. The model implements INotifyPropertyChanged to notify the view when the Properties change value. The Properties are primitives backed by fields, e.g:

private bool m_isRunning;
public bool IsRunning
{
    get { return m_isRunning; }
    private set
    {
        m_isRunning= value;
        OnPropertyChanged("IsRunning");
    }
}

protected virtual void OnPropertyChanged(string propertyName)
{
    if (String.IsNullOrEmpty(propertyName))
    {
        return;
    }
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

This works fine for primtiive values. I also have a composite object with various primitive properties and a hash table. Or, I'd like to bind to an ObservableCollection's Count property. I would like to bind my View controls to properties within the composite object, but I do not think this is possible. Something like:

       <Run Text="{Binding Path=CompositeObject.SomeInnerProperty, Mode=OneWay,  UpdateSourceTrigger=PropertyChanged}" />

This doesn't seem possible, but is there some other way? I feel like my only option is to expose properties that map in to the inner property of the composite object, but this seems like a lot of repetiion, e.g.:

public bool SomeInnerProperty
{
    get { return m_myComposite.SomeInnerProperty; }
    private set
    {
        m_myComposite.SomeInnerProperty= value;
        OnPropertyChanged("SomeInnerProperty");
    }
}
Stealth Rabbi
  • 10,156
  • 22
  • 100
  • 176
  • Does (or can) the composite object implement INotifyPropertyChanged? – Wonko the Sane Apr 01 '13 at 17:50
  • it can, yes. I'm actually looking at this and you can, apparently bind to a property of a property. If the VM is able to notify the change in the composite object, I think it will work. http://www.nbdtech.com/Free/WpfBinding.pdf – Stealth Rabbi Apr 01 '13 at 17:55
  • 2
    There's nothing wrong with binding to something like `CompositeObject.SomeInnerProperty`, however if `CompositeObject` does not implement `INotifyPropertyChanged`, then your UI won't update when `SomeInnerProperty` changes. Also, note that you can only bind to properties (with `get` and `set` methods), not fields. In regards to repetitive code, I personally use some [Visual Studio macros](http://stackoverflow.com/a/14261661/302677) to write my public properties for me, so perhaps you could look into doing something like that if you don't want to implement INPC on your `CompositeObject` – Rachel Apr 01 '13 at 18:19
  • @Rachel, this answers my question. If you put it in an answer, I can close this out. Thanks. – Stealth Rabbi Apr 01 '13 at 18:43
  • 1
    @StealthRabbi Sure, it's added :) – Rachel Apr 01 '13 at 18:49

2 Answers2

2

There's nothing wrong with binding to something like CompositeObject.SomeInnerProperty, however if CompositeObject does not implement INotifyPropertyChanged, then your UI won't get notified of the change and know that it needs to update when SomeInnerProperty changes.

Also, note that you can only bind to properties (with get and set methods), and not fields. So you can bind to public string SomeValue { get; set; } but you can't bind to public string SomeValue;

In regards dealing with repetitive code, I personally use some Visual Studio macros to write my public properties for me, so perhaps you could look into doing something like that if you don't want to implement INotifyPropertyChanged on your CompositeObject class. It should be noted that Macros were removed from Visual Studio 2012 though, so if you have a newer version you might need to use some other alternative like creating an add-in to run your macros

Community
  • 1
  • 1
Rachel
  • 130,264
  • 66
  • 304
  • 490
  • Is it possible to bind to a value in a hash table, e.g. : Binding Path=MyDerpHash[5]. I think that, even if this was possible, the view is making a big assumption about the data which probably violates MVVM. – Stealth Rabbi Apr 01 '13 at 19:19
  • @StealthRabbi You should be able to providing that's a valid property. I've used that kind of syntax every once in a while to bind to the first item in a List or Array before. The view is meant to be a reflection of the UI, so I think it's fine if the UI needs to make that kind of assumption about the data layer behind it on occasion. – Rachel Apr 01 '13 at 19:27
0

I had this same problem some time ago. Look at how I solved it: MVVM INotifyPropertyChanged conflict with base class PropertyChange

Basically I created a Base class that implemented INotifyPropertyChanged and I made all my classes inherit from that base class and data binding worked fine.

You have two options:

  1. If your model classes do not implement INPC, then create wrapper properties in your ViewModel like you suggested, or
  2. Implement INPC in your model and just expose your main object in the ViewModel, you can bind as deep as you want as long as inner properties notify changes.
Community
  • 1
  • 1
Adolfo Perez
  • 2,834
  • 4
  • 41
  • 61
  • I'm not having a INPC conflict though, just trying to figure out if it it's possible to bind to an inner property. – Stealth Rabbi Apr 01 '13 at 17:56
  • So that means you don't have a way to modify your Composite object definition to make it implement INPC or inherit from a Base class that implements it and just notify changes? – Adolfo Perez Apr 01 '13 at 18:00
  • From what I understand it is a requirement in WPF that every property you are binding to notifies changes. – Adolfo Perez Apr 01 '13 at 18:07