views:

87

answers:

1

I have a textblock bound to an object. The 2-way binding works well and as expected.

In the code-behind:

txtNumberOfPlayers.DataContext = tournament.ChipSet;

In the .xaml:

 <toolkit:NumericUpDown x:Name="txtNumberOfPlayers" Value="{Binding NumberOfPlayers, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />

In the Chipset class I raise a change notification when the NumberOfPlayers is set (OnPropertyChanged("NumberOfPlayers");)

But... when I completely reassign the object it does not update the UI unless I call the datacontext assignment again. For example, lets say I load a different chipset object.

Chipset newChipSet = LoadChipset();
tournament.ChipSet = newChipSet;

This does not update the txtNumberOfPlayers when the assignement is made. It only works if I do this:

Chipset newChipSet = LoadChipset();
tournament.ChipSet = newChipSet;
//have to call this again which seems redundant
txtNumberOfPlayers.DataContext = tournament.ChipSet;

So I thought, maybe I have to put the change notification on the Chipset object like this:

private Chipset chipset;
public Chipset ChipSet
{
    get { return chipset; }
    set
    {
        if (chipset != value)
        {
            chipset = value;
            OnPropertyChanged("ChipSet");
        }
    }
}

but that does not work.

So my questions is - how do I get the UI to update when I assign a new object to the old one without rebinding the datacontext.

Thanks!

A: 

You should specify RelativeSource to your Binding:

Value={Binding NumberOfPlayers, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type YourNamespace:YourTypeContainingChipsetProperty}}}

EDIT

Example of DependencyProperty in your case. Change YourCustomControl to class name of your control:

public static DependencyProperty ChipsetProperty = 
                                    DependencyProperty.Register("Chipset", typeof(Chipset),
                                                                                               typeof(YourCustomControl),
                                                                                               new FrameworkPropertyMetadata
                                                                                                   (null,
                                                                                                    FrameworkPropertyMetadataOptions
                                                                                                        .
                                                                                                        BindsTwoWayByDefault, ChipsetPropertyChangedCallback));

public Chipset Chipset
        {
            get { return (Chipset)GetValue(ChipsetProperty); }
            set { SetValue(ChipsetProperty, value); }
        }

private static void ChipsetPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var yourCustomControl = d as YourCustomControl;
            if (yourCustomControl != null)
            {
                //your logic on property changed goes here; don't raise OnPropertyChanged!
            }
        }
Eugene Cheverda
Thanks for replying Eugene - but it seems as though FindAncestor is not supported on Silverlight 4?I read up about it on WPF though - would that have fixed my problem? The binding currently works as is - it's just when I reassign the object in code that I have to set the datacontext again?
Rodney
No, usually you shouldn't. If this will not work so define your Chipset Property as DependencyProperty. You may specify there CallBack function that will handle your logic with DataContext if you need it.
Eugene Cheverda
Ok, I found this link - http://csharperimage.jeremylikness.com/2009/07/silverlight-datacontext-changed-event.html - it seems like a lot of work versus just setting the datacontext again? This is all a bit new to me but I just want my grid to update to the new datacontext.
Rodney