Data binding 对象重新分配时的数据绑定/属性更改通知(Silverlight 4/C)

Data binding 对象重新分配时的数据绑定/属性更改通知(Silverlight 4/C),data-binding,silverlight-4.0,Data Binding,Silverlight 4.0,我有一个绑定到对象的文本块。双向绑定工作正常,符合预期 在代码隐藏中: txtNumberOfPlayers.DataContext = tournament.ChipSet; 在.xaml中: <toolkit:NumericUpDown x:Name="txtNumberOfPlayers" Value="{Binding NumberOfPlayers, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnException

我有一个绑定到对象的文本块。双向绑定工作正常,符合预期

在代码隐藏中:

txtNumberOfPlayers.DataContext = tournament.ChipSet;
在.xaml中:

 <toolkit:NumericUpDown x:Name="txtNumberOfPlayers" Value="{Binding NumberOfPlayers, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />
分配时,这不会更新TXTNumberOfPlayer。只有当我这样做时,它才会起作用:

Chipset newChipSet = LoadChipset();
tournament.ChipSet = newChipSet;
//have to call this again which seems redundant
txtNumberOfPlayers.DataContext = tournament.ChipSet;
所以我想,也许我必须像这样在芯片组对象上放置更改通知:

private Chipset chipset;
public Chipset ChipSet
{
    get { return chipset; }
    set
    {
        if (chipset != value)
        {
            chipset = value;
            OnPropertyChanged("ChipSet");
        }
    }
}
但这是行不通的

所以我的问题是-当我将新对象分配给旧对象时,如何让UI更新,而不重新绑定datacontext


谢谢

您应该指定绑定的相对资源:

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

您案例中的DependencyProperty示例。将CustomControl更改为控件的类名:

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-但似乎Silverlight 4不支持FindAncestor?我在WPF上读到了这篇文章——这能解决我的问题吗?绑定当前按原样工作-仅当我在代码中重新分配对象时,我必须再次设置datacontext?不,通常不应该。如果这不起作用,那么将芯片组属性定义为DependencyProperty。如果需要的话,您可以指定回调函数来处理DataContext的逻辑。好的,我找到了这个链接——与再次设置DataContext相比,似乎需要做很多工作?这对我来说有点新鲜,但我只想让我的网格更新到新的datacontext。
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!
            }
        }