可观察集合从 xaml 初始化 - Silverlight

发布于 2024-11-19 04:45:03 字数 1261 浏览 2 评论 0原文

我在 Silverlight UserControl 中有以下 DependencyProperty:

public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register( "Columns", typeof( ObservableCollection<FilterableDataGridColumn> ), typeof( FilterableDataGridControl ), new PropertyMetadata( new ObservableCollection<FilterableDataGridColumn>(), new PropertyChangedCallback( OnColumnsChanged ) ) );

public ObservableCollection<FilterableDataGridColumn> Columns {
    get {
        return ( ObservableCollection<FilterableDataGridColumn> )GetValue( ColumnsProperty );
    }
    set {
        SetValue( ColumnsProperty, value );
    }
}

static void OnColumnsChanged( object sender, DependencyPropertyChangedEventArgs args ) {
    ...
}

我正在尝试从 xaml 初始化它:

<my:FilterableDataGridControl ... >
    <my:FilterableDataGridControl.Columns>
        <my:FilterableDataGridColumn Header="Name" PropertyName="Name" ColumnType="Text" />
        <my:FilterableDataGridColumn Header="Type" PropertyName="Type" ColumnType="Text" />
    </my:FilterableDataGridControl.Columns>
</my:FilterableDataGridControl>

但它不起作用!没有异常,没有错误,但没有调用 OnColumnsChanged。

有什么想法吗?

I have the following DependencyProperty in a Silverlight UserControl:

public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register( "Columns", typeof( ObservableCollection<FilterableDataGridColumn> ), typeof( FilterableDataGridControl ), new PropertyMetadata( new ObservableCollection<FilterableDataGridColumn>(), new PropertyChangedCallback( OnColumnsChanged ) ) );

public ObservableCollection<FilterableDataGridColumn> Columns {
    get {
        return ( ObservableCollection<FilterableDataGridColumn> )GetValue( ColumnsProperty );
    }
    set {
        SetValue( ColumnsProperty, value );
    }
}

static void OnColumnsChanged( object sender, DependencyPropertyChangedEventArgs args ) {
    ...
}

I'm trying to initialize it from xaml:

<my:FilterableDataGridControl ... >
    <my:FilterableDataGridControl.Columns>
        <my:FilterableDataGridColumn Header="Name" PropertyName="Name" ColumnType="Text" />
        <my:FilterableDataGridColumn Header="Type" PropertyName="Type" ColumnType="Text" />
    </my:FilterableDataGridControl.Columns>
</my:FilterableDataGridControl>

But it doesn't work! No exception, no error, but the OnColumnsChanged is not invoked.

Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

海拔太高太耀眼 2024-11-26 04:45:03

我完整地模拟了您的示例,基本上您期望 ObservableCollection 的内容更改发生属性更改事件。仅当集合本身被替换时才会触发事件处理程序,而您仅替换子元素而不替换集合。

唯一会被命中的代码是 getter:

get { return (ObservableCollection<FilterableDataGridColumn>)GetValue(ColumnsProperty); }

可能有一种更优雅的方式将事件连接到动态创建的属性,但这会起作用:

    public ObservableCollection<FilterableDataGridColumn> Columns
    {
        get
        {
            var columns = (ObservableCollection<FilterableDataGridColumn>)GetValue(ColumnsProperty);
            columns.CollectionChanged -= columns_CollectionChanged; // Disconnect each time we reconnect
            columns.CollectionChanged += columns_CollectionChanged;
            return columns;
        }
        set
        {
            var columns = (ObservableCollection<FilterableDataGridColumn>)GetValue(ColumnsProperty);
            if (columns != null)
            {
                columns.CollectionChanged -= columns_CollectionChanged; // Disconnect each time we change collection
            }
            SetValue(ColumnsProperty, value);
        }
    }

    void columns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        // This will get hit
    }

这是添加一个 CollectionChanged< /code> 处理集合,而不是监听集合本身被替换。

*您会注意到 setter 会费尽心思从之前的任何集合中删除 handler。这是一种“以防万一”措施,否则与此属性断开连接的集合在删除后仍会报告更改。这并不是使其适用于您的资源添加的初始集合的必要条件

I mocked up your example in full and basically you are expecting a property change event to occur for the content changes of an ObservableCollection. Your event handler is only triggered if the collection itself is replaced, whereas you are replacing child elements only and not the collection.

The only piece of your code that will get hit is the getter:

get { return (ObservableCollection<FilterableDataGridColumn>)GetValue(ColumnsProperty); }

There may be a more graceful way to hookup events to dynamically created properties, but this will work:

    public ObservableCollection<FilterableDataGridColumn> Columns
    {
        get
        {
            var columns = (ObservableCollection<FilterableDataGridColumn>)GetValue(ColumnsProperty);
            columns.CollectionChanged -= columns_CollectionChanged; // Disconnect each time we reconnect
            columns.CollectionChanged += columns_CollectionChanged;
            return columns;
        }
        set
        {
            var columns = (ObservableCollection<FilterableDataGridColumn>)GetValue(ColumnsProperty);
            if (columns != null)
            {
                columns.CollectionChanged -= columns_CollectionChanged; // Disconnect each time we change collection
            }
            SetValue(ColumnsProperty, value);
        }
    }

    void columns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        // This will get hit
    }

This is adding a CollectionChanged hander to the collection, rather than listening for the collection itself to be replaced.

*You will note the setter goes to the trouble of removing the hander from any previous collection. This is a "just in case" measure as otherwise a collection disconnected from this property would still report changes after removal. This is not required to make it work for the initial collection your property adds

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文