依赖属性未更新 Silverlight 4。

3

我在更新UserControl/View的一个依赖属性时遇到了一些问题。

我有一个主视图(MainView.xaml),其中声明了一系列其他用户控件。其中一个如下所示:

<local:Snapshot BrandID="{Binding Path=Session.Test}" />

我的 Snapshot.xaml 文件中有一个 TextBlock:

<TextBlock Text="Sample text" x:Name="brandIDTBlock" />

我的Snapshot.xaml.cs文件有以下依赖属性:

public string BrandID
{
    get { return (string)GetValue(BrandIdProperty); }
    set { SetValue(BrandIdProperty, value); }
}

public static readonly DependencyProperty BrandIdProperty = DependencyProperty.Register("BrandID", typeof(string), typeof(Snapshot), new PropertyMetadata(new PropertyChangedCallback(OnBrandIdChange)));

private static void OnBrandIdChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var control = (Snapshot)d;
    control.brandIDTBlock.Text = (string)e.NewValue;
}

Session是MainView的一个属性,当Session对象中的Test属性发生变化时,我希望我的brandIDTBlock TextBlock得到更新。

Test属性声明如下:

private string _test = "Test Value Binding";

public string Test 
{
    get { return _test; }
    set { _test = value; } 
}

现在某些东西正在工作,当我运行应用程序时,我可以看到“测试值绑定”在我的视图中正确显示,问题是当Test的值在我的Session对象中更改时,更改不会传播到视图。

我还尝试实现INotifyPropertyChanged接口,方法如下:

public string Test
{
    get { return _test; }
    set
    {
        _test = value;
        OnPropertyChanged("Test");
    }
}

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string name)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(name));
    }
}

但它仍然没有更新。

更新:事实证明这是一个新手错误。在我的Snapshot.xaml.cs中,我正在更改处理饼图的代码块中的数据上下文。我通过更改绑定表达式,使绑定元素成为Snapshot.xaml的父级(在我的情况下为StackPanel 'sp' ({Binding ElementName=sp, Path=DataContext.Session.Test}))来解决了这个问题。除了这个愚蠢的错误之外,我原始代码中真正缺少的是INotifyPropertyChanged实现,双向绑定是不必要的。

谢谢

Luis


这是一个结构良好的问题,但是您是否实际上已经将 INotifyPropertyChanged 添加到了 class Session 声明行中? - AnthonyWJones
是的,Session 实现了 INotifyPropertyChanged 接口。 - LCL
3个回答

1

您需要在绑定中添加Mode=TwoWay

<local:Snapshot BrandID="{Binding Path=Session.Test, Mode=TwoWay}" />

OneWay 是默认设置,它只允许 UI 更新绑定的值。如果要在绑定的值更改后使 UI 更改,则需要使用 TwoWay

您还需要引发属性更改事件,以让 UI 知道已经发生了一些更改。

唯一需要注意的是检查您是否正确设置了视图的 DataContext


3
这里不需要双向绑定。如果使用了“TextBox”并且希望用户可以通过键入新值来更改值,则会使用双向绑定。在这种情况下,默认的单向绑定就足够了。 - AnthonyWJones

0
绑定不正确。通过仅使用路径的 {Binding},您尝试绑定到通过 DataContext 公开的数据。您设置了 DataContext 吗?
编辑
您的代码中还有更多错误:
control.brandIDTBlock.Text = (string)e.NewValue;
此行不属于 PropertyChanged 处理程序。并且可能会让您认为绑定正在工作。
我没有时间添加一个正确的示例,所以这里是一个链接,应该可以帮助您入门。

在这种情况下,即使原始值也不会出现,问题是值的更改没有传播。 - AnthonyWJones
我不太确定如何设置DataContext,但实际上它是这样工作的:我有一个Column类,它有一个DataTemplate ContentTemplate,返回我的MainView.xaml(同样它有一个header,这部分可以工作),它是Column类,它引用了我的Session对象。因此,当我在MainView中说Session.Text时,它从我的Column类获取Session对象并尝试读取其Test属性。MainView在其内部使用另一个控件(Snapshot),在该控件的.cs文件中,我有需要更新的依赖属性。我应该在哪里设置数据上下文? - LCL
你的代码还有更多问题。看起来你还没有理解相关概念和职责。因此,我在我的回答中添加了一个教程链接。 - Emond
我不同意,但是在我看来那行代码看起来很好。 - AnthonyWJones
@AnthonyWJones:已注意。我不喜欢那行代码,因为它添加了一个意外的依赖项,通常是通过绑定创建的。 - Emond

0

当您的视图模型中的Test值发生更改时,它是否会“更改”,因为您已替换了返回到主视图模型的Session属性的对象。如果是这样,您需要让主视图模型也实现INotifyPropertyChanged并在更新Session属性时调用PropertyChanged。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接