开发者

Databinding/PropertyChanged Notification on object reassignement (Silverlight 4/C#)

开发者 https://www.devze.com 2023-01-08 02:47 出处:网络
I have a textblock bound to an object. The 2-way binding works well and as expected. In the code-behind:

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开发者_如何学Go new object to the old one without rebinding the datacontext.

Thanks!


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!
            }
        }
0

精彩评论

暂无评论...
验证码 换一张
取 消