【问题标题】:Dependency property not updating Silverlight 4依赖属性不更新 Silverlight 4
【发布时间】:2011-08-05 09:37:38
【问题描述】:

我在更新 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; } 
}

现在 somehting 正在工作,因为当我运行应用程序时,我看到“测试值绑定”正确显示在我的视图中,问题是当我的 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 中,我正在更改处理饼图的片段代码中的数据上下文。我通过更改绑定 epression 来解决此问题,以便绑定元素成为 Snapshot.xaml 的父级,在我的情况下为 StackPanel 'sp'({Binding ElementName=sp,Path=DataContext.Session.Test})。除了这个愚蠢的错误之外,我的原始代码中真正缺少的是 INotifyPropertyChanged 实现,TwoWay 绑定是不必要的。

谢谢

路易斯

【问题讨论】:

  • 这是一个结构良好的问题,但是您是否真的将INotifyPropertyChanged 添加到class Session 声明行?
  • 是的,Session 实现了 INotifyPropertyChanged。

标签: silverlight dependency-properties


【解决方案1】:

您需要将Mode=TwoWay 添加到您的绑定中:

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

OneWay 是默认值,它允许 UI 仅更新绑定值。要在绑定值更改后更改 UI,您需要 TwoWay。

您还需要引发属性更改事件以让 UI 知道某些内容已更改。

唯一的另一件事是检查您是否正确设置了视图的DataContext。

【讨论】:

  • 这里不需要双向绑定。如果正在使用 TextBox 并且希望用户能够通过键入新值来更改值,则将使用 TwoWay。在这种情况下,默认的 OneWay 绑定很好。
【解决方案2】:

绑定不正确。通过使用仅带有路径的 {Binding},您可以尝试绑定到通过 DataContext 公开的数据。你设置了 DataContext 了吗?

编辑

你的代码有更多错误:

control.brandIDTBlock.Text = (string)e.NewValue;

此行不属于 PropertyChanged 处理程序。并且可能会让您认为绑定有效。

我没有时间添加一个正确的例子所以here is a link that should get you started.

【讨论】:

  • 在这种情况下,即使原始值也不会显示出来,问题是值的变化不是正确的。
  • 我不太确定如何设置 DataContext,但这是它实际工作的方式,我有一个 Column 类,它有一个 DataTemplate ContentTemplate,它返回我的 MainView.xaml(类似地它有一个标题,这部分有效),它是 Column 类,它引用了我的 Session 对象。因此,当我在 MainView 中说 Session.Text 时,它会从我的 Column 类中获取 Session 对象并尝试读取它的 Test 属性。 MainView 在其中使用另一个控件(快照),并且在该控件的 .cs 文件中,我有需要更新的依赖项属性。我应该在哪里设置数据上下文?
  • 您的代码有更多错误。看起来你还没有理解这些概念和职责。因此,我在答案中添加了指向教程的链接。
  • 再说一次,我不同意这条线对我来说很好。
  • @AnthonyWJones:注意。我不喜欢那行,因为它添加了通常通过绑定创建的意外依赖项。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多