【问题标题】:Xaml Behavior DP not updatedXaml 行为 DP 未更新
【发布时间】:2016-09-22 13:31:36
【问题描述】:

我有一个使用托管 UWP 行为 SDK 的 UWP 应用程序。 我编写了一个自定义行为,它有两个依赖属性,其中一个是 ObservableCollection。

每当我更新集合中的项目时,我都会确保为集合调用 PropertyChanged。

但是,Dependency 属性并未更新。

我的代码:

<trigger:CustomBehavior ItemIndex="{x:Bind ItemIndex}"
     Presences="{Binding ElementName=Box,
         Path=DataContext.CustomCollection,
             UpdateSourceTrigger=PropertyChanged, Converter={StaticResource TestConverter}}" />

我的 TestConverter 显示当我更新集合中的项目时,updatesource 触发器正在工作。然而,我行为中的依赖属性并没有触发 Changed 事件。当我更改整个自定义集合时,DP 会更新,当我只更改一项时,它不会。

到目前为止的研究表明 DependencyObject.SetValue 只是检查对象是否已更改,如果有一项更改,它会认为集合根本没有更改?这是真的吗?如果是,我该如何克服?

谢谢

【问题讨论】:

  • 首先注意:“当我更新集合中的项目时,updatesource 触发器正在工作”是一个常见的误解。在单向绑定上设置UpdateSourceTrigger=PropertyChanged 无效,它只控制在目标更改时如何更新绑定的源,即仅在双向或单向源绑定中有效。也就是说,更新集合中的项目然后引发 PropertyChanged 事件也没有任何效果,因为集合 instance 没有更改,并且 PropertyChanged 事件被静默忽略。
  • 要么替换整个集合,要么在 Presences 属性的 PropertyChangedCallback 中为 INotifyCollectionChanged.CollectionChanged 事件注册一个处理程序。
  • 美丽。您可以将此作为答案发布,以便我接受吗?

标签: xaml uwp behavior


【解决方案1】:

集合类型依赖属性通常应该声明为最基本的集合类型IEnumerable。通过这种方式,您可以为属性分配各种实际的集合类型,包括那些实现 INotifyCollectionChanged 的集合类型,例如 ObservableCollection&lt;T&gt;

您将在运行时检查集合类型是否实际实现了接口,并可能附加和分离CollectionChanged 事件的处理程序方法。

public class CustomBehavior : ...
{
    public static readonly DependencyProperty PresencesProperty =
        DependencyProperty.Register(
            "Presences", typeof(IEnumerable), typeof(CustomBehavior),
            new PropertyMetadata(null,
                (o, e) => ((CustomBehavior)o).OnPresencesPropertyChanged(e)));

    private void OnPresencesPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        var oldCollectionChanged = e.OldValue as INotifyCollectionChanged;
        var newCollectionChanged = e.NewValue as INotifyCollectionChanged;

        if (oldCollectionChanged != null)
        {
            oldCollectionChanged.CollectionChanged -= OnPresencesCollectionChanged;
        }

        if (newCollectionChanged != null)
        {
            newCollectionChanged.CollectionChanged += OnPresencesCollectionChanged;
            // in addition to adding a CollectionChanged handler, any
            // already existing collection elements should be processed here
        }
    }

    private void OnPresencesCollectionChanged(
        object sender, NotifyCollectionChangedEventArgs e)
    {
        // handle collection changes here
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 2020-02-06
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多