【问题标题】:How to read the contents of a bound ObservableCollection in a custom control如何在自定义控件中读取绑定的 ObservableCollection 的内容
【发布时间】:2012-01-07 21:23:42
【问题描述】:

我有一个第三方用户控件,我必须使用它来显示地图,不幸的是,这个第三方控件不支持数据绑定,但我必须使用它的框架只能通过绑定传递数据。

示例代码:-

就目前而言,我可以将第三方控件添加到页面的 XAML 文件中,如下所示:-

<ViewerControl:Viewer x:Name="Viewer"
                      HorizontalAlignment="Stretch"
                      VerticalAlignment="Stretch"
                      MouseMove="OnMouseMove">
</ViewerControl:Viewer>

然后我可以定义一个地图层并将其添加到代码隐藏中的地图中,如下所示:-

var layerDefinition = new WMSLayerDefinition("AFG_AGS_1M_MFS",
                                             new Extent(59.7812, 26.9152, 75.5985, 40.9476),
                                             "EPSG:4326") { IsSelectable = true };
var wmsLayer = new WMSLayer(Viewer.GetViewController(),
                            layerDefinition,
                            "http://ogc.bgs.ac.uk/cgi-bin/BGS_AGS_EN_Bedrock_and_Structural_Geology/wms/");
Viewer.GetLayerManager().GetLayerGroup(layerGroupName).AddLayer(wmsLayer);

我希望能够将 WMSLayer 的ObservableCollection(或我自己的模型,比查看器使用的模型更通用一点)绑定到查看器,但是因为我没有访问查看器代码我假设我需要编写一个wrapper 控件。

据我所知,wrapper 控件需要包含第三方用户控件的实例和 DependencyProperty 以允许我绑定地图层数据的 ObservableCollection 以便我可以将其用作第三方用户控件方法的参数。

我已经阅读了很多自定义用户控件中的绑定示例,让我头晕目眩,不幸的是,它们都处理在 UI 中呈现绑定数据。我想要做的是将绑定数据传递给另一个负责演示的控件,我知道这不是 Silverlight 控件 工作的真正正确方式,但因为我没有影响关于第三方用户控件的设计,我看不到任何其他方式。

谁能帮助我了解如何访问我的wrapper usercontrol 中的绑定数据并将其传递给第三方 usercontrol 公开的方法?

提前致谢:o)

【问题讨论】:

  • 这需要一些示例代码才能让任何人猜测适当的解决方案。
  • 谢谢,公平点,已添加代码示例,希望对您有所帮助...

标签: .net binding silverlight-4.0 user-controls observablecollection


【解决方案1】:

这个答案在某种程度上取决于谁拥有ObservableCollection,但应该具有足够的可塑性以满足您的需求。

一个简单的解决方案是挂接ObservableCollection提供的INotifyCollectionChanged接口:

// FrameworkElement.DataContextChanged (Window/Page/UserControl/etc)
private void OnDataContextChanged(object sender,
    DependencyPropertyChangedEventArgs e)
{
    // if your DataContext is some other type, do the appropriate casting
    var oldValue = e.OldValue as ObservableCollection<YourLayer>();
    if (oldValue != null)
    {
         oldValue.CollectionChanged -= LayerCollectionChanged;
    }

    var newValue = e.NewValue as ObservableCollection<YourLayer>();
    if (newValue != null)
    {
         newValue.CollectionChanged += LayerCollectionChanged;
    }
}

在适当的处理程序中建立连接后,您只需侦听修改并手动处理层管理器中的添加/删除:

private void LayerCollectionChanged(object sender,
    NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
    case NotifyCollectionChangedAction.Add:
        foreach (YourLayer layer in e.NewItems)
        {
            // custom method to handle conversion from YourLayer to WMSLayer
            this.AddLayer(layer);
        }
        break;

    case NotifyCollectionChangedAction.Remove:
        foreach (YourLayer layer in e.OldItems)
        {
            // custom method to remove a WMSLayer matching the YourLayer
            this.RemoveLayer(layer);
        }
        break;

     // handle the other notifications as you see fit
    }
}

【讨论】:

  • 谢谢,我之前为 DependencyProperty 尝试过类似的方法,但对于 DataContext 却没有。添加您的代码后,我似乎无法将您的 OnDataContextChanged 连接到构造函数中的事件。
  • 构造函数到底是什么?
  • 我想我要问的是应该调用OnDataContextChanged 或者应该分配什么事件,因为UserControl 上似乎没有DataContextChanged 事件我可以将此处理程序分配给。
  • 我想了解您出于教育目的提出的建议。我已经使用DependencyProperty 解决了最初的问题,还使用了here 给出的建议,我还能够监听ObservableCollection 中项目属性的变化。感谢您的帮助,我将在整理后发布我所采用的解决方案的详细信息。
  • 啊,再次阅读 WPF MSDN 而不是 SL4。使用DependencyProperty 是对的,但是,您不需要将PropertyChanged 连接到ObservableCollection。您可以使用 DependencyProperty 的 Changed 事件而不是 DataContextChanged 来提供我展示的接线。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-24
  • 2015-11-04
相关资源
最近更新 更多