views:

103

answers:

2

I have a complex value object class that has 1) a number or read-only properties; 2) a private constructor; and 3) a number of static singleton instance properties [so the properties of a ComplexValueObject never change and an individual value is instantiated once in the application's lifecycle].

public class ComplexValueClass
{
    /* A number of read only properties */
    private readonly string _propertyOne;
    public string PropertyOne
    {
        get
        {
            return _propertyOne;
        }
    }

    private readonly string _propertyTwo;
    public string PropertyTwo
    {
        get
        {
            return _propertyTwo;
        }
    }

    /* a private constructor */
    private ComplexValueClass(string propertyOne, string propertyTwo)
    {
        _propertyOne = propertyOne;
        _propertyTwo = PropertyTwo;
    }

    /* a number of singleton instances */
    private static ComplexValueClass _complexValueObjectOne;
    public static ComplexValueClass ComplexValueObjectOne
    {
        get
        {
            if (_complexValueObjectOne == null)
            {
                _complexValueObjectOne = new ComplexValueClass("string one", "string two");
            }
            return _complexValueObjectOne;
        }
    }

    private static ComplexValueClass _complexValueObjectTwo;
    public static ComplexValueClass ComplexValueObjectTwo
    {
        get
        {
            if (_complexValueObjectTwo == null)
            {
                _complexValueObjectTwo = new ComplexValueClass("string three", "string four");
            }
            return _complexValueObjectTwo;
        }
    }
}

I have a data context class that looks something like this:

public class DataContextClass : INotifyPropertyChanged
{


    private ComplexValueClass _complexValueClass;
    public ComplexValueClass ComplexValueObject
    {
        get
        {
            return _complexValueClass;
        }
        set
        {
            _complexValueClass = value;
            PropertyChanged(this, new PropertyChangedEventArgs("ComplexValueObject"));
        } 
    }
}  

I would like to write a XAML binding statement to a property on my complex value object that updates the UI whenever the entire complex value object changes. What is the best and/or most concise way of doing this? I have something like:

<Object Value="{Binding ComplexValueObject.PropertyOne}" />

but the UI does not update when ComplexValueObject as a whole changes.

A: 

You don't notify on changes to PropertyOne so UI will not update. Instead bind to ComplexValueObject and use value converter to get the property value.

<Object Value="{Binding Path=ComplexValueObject, Converter={StaticResource ComplexValueConverter}, ConverterParameter=PropertyOne}" /> 

public class ComplexValueConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    ComplexValue cv = value as ComplexValue;
    string propName = parameter as string;
    switch (propName)
    {
      case "PropertyOne":
        return cv.PropertyOne;
      case "PropertyTwo":
        return cv.PropertyTwo;
      default:
        throw new Exception();
    }
  }

  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}
Wallstreet Programmer
That does work. I am wondering if there is a pure XAML way to accomplish the same thing though.
Gus
You mean with no code behind at all and keep your data classes as is??? Write a user control with a dependency property of type ComplexValueClass which will invalidate itself when the dependency property changes.
Wallstreet Programmer
+1  A: 

Your original scenario should work just fine because in most cases Bindings recognize change notifications on any part of their property path. I in fact tried out the code you posted to confirm and it does work just fine.

Are there other complexities you may not be expressing in your stripped down sample? The primary one I can think of would be collections->ItemsSource Bindings but there could be something related to the property you're assigning the bound value to (since it's obviously not an Object) or something else entirely.

John Bowen