none
Binding to whole object - not updating

    Question

  • I'm using Binding to the whole object (without specifying the field)
    Foreground ="{Binding Converter={StaticResource clrColorConverter}}" 
    and accessing it's fields in converter.
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    MyObj data = value as MyObj;
    if( data.field1 == data.field2)
    return new SolidColorBrush(Colors.Black);
    }
    This works, but only once - for initial display. The problem is that when object properties change, the Foreground is not updated (with others everything is OK). MyObj implements INotifyPropertyChanged and calls NotifyPropertyChanged with particular field name - this works for the same field update.
    Please let me know how should I notify system, that whole object (not just one field) was changed for it to re-calculate the Foreground.
    Thanks!
    Monday, August 03, 2009 9:02 AM

Answers

  • Hi,

    Instead of using Binding and converter, you could handling INotifyPropertyChanged.PropertyChanged event menually.

    1. register propertychanged event of datacontext in control's loaded event
    2. set foreground value in propertychanged event handler

    Thanks,

    Friday, August 07, 2009 4:22 AM

All replies

  • From the code you have provided, Its not possible to judge, What exacty went wrong fo not getting the correct foreground;

    Let me ust provide a code, that works fine;

    <cmd:ForeGroundConverter x:Key="ForegroundTBConverter"/>

    <TextBlock Foreground="{Binding , Converter={StaticResource ForegroundTBConverter}, ConverterParameter=''}"/>

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

    {

    MyObj data = value as MyObj;

    if (data.field1 == data.field2)

    return new SolidColorBrush(Colors.Black);

    else

    return new SolidColorBrush(Colors.Red);

    }

     

    ---

    Make sure that Colloction is Observable, and make sure that you Notify PropertyChanged

    public ObservableCollection<TreeviewNode> Items

    {

    get

    {

    return _items;

    }

    set

    {

    _items =
    value;NotifyPropertyChanged("Items");

    }

    }

    Monday, August 03, 2009 9:20 AM
  •  You will have to inherit INotifyPropertyChanged in your class.

    http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

    Monday, August 03, 2009 9:25 AM
  • That all works fine only if your object is something enumerable so you can use ObservableCollection. But if you just have a class with two properties and want to bind the whole class as far as I know there is no interface to help you with binding. Sorry.
    Monday, August 03, 2009 9:27 AM
  •  As I've stated, the MyObj implements INotifyPropertyChanged. I also use ObservableCollection<MyObj > MyObjs, which is items source for MyGrid - MyGrid.ItemsSource = MyObjs. all fields in the Grid are updated, as they are bind to specific fields: <data:DataGridTextColumn x:Name="Field1" Binding="{Binding field1}"/>

    The problem I have is with binding to the whole MyObj object (without path=field):

    Foreground ="{Binding Converter={StaticResource clrColorConverter}}"
    Converter is not called after MyObj.field1 property is changed. Although this property is updated in the other Grid column. The question is - how to make Converter be called??
    Monday, August 03, 2009 9:59 AM
  •  I've could use IMultiValueConverter, but it's not present in Silverlight. Was forced to add new property (that is calculated based on the other fields) and when one of the other fields is changed, added NotifyPropertyChanged("NewProperty") just after the NotifyPropertyChanged("field1");

    If someone has more elegant solution, please let me know. Thanks

    Monday, August 03, 2009 10:38 AM
  • If a PropertyChanged is notified correctly, then it will trigger the Converter; (It is not possible to trigger the converter by any manuall process;)

    Make sure that u notify the property change; Trigger the property changed Event and try whether the propery is getting changed..

     

    Tuesday, August 04, 2009 3:10 AM
  • Hi,

    Instead of using Binding and converter, you could handling INotifyPropertyChanged.PropertyChanged event menually.

    1. register propertychanged event of datacontext in control's loaded event
    2. set foreground value in propertychanged event handler

    Thanks,

    Friday, August 07, 2009 4:22 AM
  • I have a slightly more complex scenario -

    I have a collection of objects of type A. Each of them has a collection of B's .

    I show all the A's in a grid , where for each row (A) I call a converter , finds a specific B (let's say according to a max value of one of B's properties) and show this max value as the converter output .

    When I update the B property value I want to tell the grid (or the specific row , specific object : A)  : something changed , please do the binding all over. The events fires for B because B's property has changed , but not for A that contains a list of B's (the list of B's hasn't changed) .

    If the solution involves calling the object (B) OnPropertyChanged , I'll have to somehow pass it from the server (I'm using RIA services).

    I hope my question is clear.

    Thanks

    Friday, September 18, 2009 6:10 PM
  • I have a similar problem (I think ;) - I need to bind a textblock to a resource string which uses String.Format as a Converter Param in 2-way binding. It was not getting updated when the values changed as I was binding to the whole object and not a property.

     This thread solved the problem for me (in Silverlight).

    Friday, July 02, 2010 10:54 AM
  • This is by far an elegant solution, but works.

    Add another property to your class:

     

    public MyClass MySelf
    {
    get
    {
    return this;
    }
    }
    
    public void RaiseSelf()
    {
    //raise propertychanged for "MySelf"
    }
    

    You can call RaiseSelf from outside your class or from the "set" of the properties you need.

    Then change your binding to:

    Foreground ="{Binding MySelf Converter={StaticResource clrColorConverter}}"
    Wednesday, February 29, 2012 5:12 AM