如何读取自定义控件中绑定的 ObservableCollection 的内容

发布于 2024-12-18 17:30:32 字数 1517 浏览 1 评论 0原文

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

示例代码:-

就目前情况而言,我可以将第三方控件添加到页面的 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 控件需要包含第三方用户控件的实例和 DependencyProperty 以允许我绑定 ObservableCollection > 地图层数据,以便我可以将其用作第三方用户控件上的方法的参数。

我读过太多自定义用户控件中的绑定示例,让我头晕目眩,不幸的是,它们都涉及在 UI 中呈现绑定数据。我想要做的是将绑定数据传递给另一个负责演示的控件,我知道这并不是 Silverlight 控件 真正正确的工作方式,但因为我没有影响力通过第三方用户控件的设计,我看不到任何其他解决方法。

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

预先感谢:o)

I have a third party usercontrol that I have to use to display a Map, unfortunately this third party control does not support data binding but the framework I have to use it in can only pass data via binding.

Example code:-

As things stand I can add the third party control to a page's XAML file like this:-

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

Then I can define a map layer and add it to the map in the codebehind like this:-

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);

What I would like to be able to do is bind an ObservableCollection of WMSLayer (or my own model that is a little more generic than the one used by the viewer) to the viewer, however as I don't have access to the viewer code I'm assuming that I would need to write a wrapper control.

As far as I can see the wrapper control would need to contain an instance of the third party usercontrol and a DependencyProperty to allow me to bind a ObservableCollection of Map Layer data so that I can use it as the parameters for the methods on the third party usercontrol.

I have read so many examples of binding in custom usercontrols that my head is spinning, unfortunately they all deal with presenting the bound data in the UI. What I want to do is pass the bound data on to another control that will take care of the presentation, I know that this is not really the correct way for Silverlight controls to work but as I have no influence over the design of the third party usercontrol I can't see any other way around this.

Can anyone help me to understand how I can access the bound data in my wrapper usercontrol and pass it into the methods exposed by the third party usercontrol please?

Thanks in advance :o)

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

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

发布评论

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

评论(1

九局 2024-12-25 17:30:32

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

一个简单的解决方案是连接到 INotifyCollectionChangedObservableCollection 提供的接口:

// 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
    }
}

This answer is somewhat dependent on who owns the ObservableCollection, but should be malleable enough to meet your needs.

A simple solution is to hook up to the INotifyCollectionChanged interface provided by the ObservableCollection:

// 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;
    }
}

Once you've established the connection in an appropriate handler, you just listen for modifications and manually handle the adding/removing from your layer manager:

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