1

我将 Silverlight 5 与 MVVM 一起使用。

我有一个 ViewModel 是Singleton。ViewModel 公开了PointCollection我用来Polyline在我的一个视图中绘制 a 的 a。

如果我尝试Polyline在第二个视图中绘制相同的内容,通过数据绑定到另一个视图,PointCollection我会得到一个“值不在预期范围内”的异常。

据我所知(以我有限的 Silverlight 知识),这是由于PointCollections不可共享的事实造成的。

有解决方法吗?如何获得与第一条相同的第二条折线?我想同时将两条折线数据绑定到一个 PointCollection

编辑:我还没有找到解决方案,但有人在这里遇到同样的问题。据微软称:

此 MSDN 页面提到某些对象不可共享,并且会生成“值超出范围”异常。 http://msdn.microsoft.com/en-us/library/system.windows.resourcedictionary(VS.95).aspx

PointCollection 页面还提到它不可共享。 http://msdn.microsoft.com/en-us/library/system.windows.media.pointcollection(VS.95).aspx

目前,这是设计行为。但是,我们正在对此进行评估,以查看我们是否可以更改行为或至少更改异常文本。

4

3 回答 3

1

我在这里找到了一个解决方案:在 getter 中复制 PointCollection。

    private PointCollection sourcePoints;
    public PointCollection SourcePoints
    {
        get
        {
            // create a new instance of PointCollection for binding
            PointCollection newPoints = new PointCollection();
            foreach (Point p in sourcePoints)
            {
                newPoints.Add(p);
            }
            return newPoints;
        }
于 2012-01-12T10:54:18.640 回答
0

也许您的 PointCollection 已冻结,这会造成麻烦。

MSDN:

Freezable 特性:因为它继承自 Freezable 类,所以 PointCollection 类提供了几个特殊特性:PointCollection 对象可以声明为资源、在多个对象之间共享、只读以提高性能、克隆和线程安全。有关 Freezable 对象提供的不同功能的更多信息,请参阅 Freezable 对象概述。

于 2012-01-11T14:09:34.767 回答
0

看看这个问题:为什么这个数据绑定不起作用?

在这一个也是:第二次绑定到 PointCollection 没有被渲染

由于您提供的细节很少,我不太确定发生了什么,但这些帖子可能会有所帮助。如果没有,请发布您的代码。

我做了一些测试,我能想到的最好的解决方案是:

using System.ComponentModel;
using System.Windows;
using System.Windows.Media;

namespace SilverlightApplication6
{
    public class DemoVM : INotifyPropertyChanged
    {
        #region PointsClone Property
        private PointCollection _pointsClone;
        public PointCollection PointsClone
        {
            get
            {
                return _pointsClone;
            }
            set
            {
                if (_pointsClone != value)
                {
                    _pointsClone = value;
                    OnPropertyChanged("PointsClone");
                }
            }
        }
        #endregion

        #region Points Property
        private PointCollection _points;
        public PointCollection Points
        {
            get
            {
                return _points;
            }
            set
            {
                if (_points != value)
                {
                    _points = value;
                    PointsClone.Clear();
                    foreach (var point in _points)
                    {
                        PointsClone.Add(point);
                    }
                    OnPropertyChanged("Points");
                }
            }
        }
        #endregion

        public DemoVM()
        {
            PointsClone = new PointCollection();
            Points = new PointCollection();
        }

        public void AddPoint(Point point)
        {
            Points.Add(point);
            PointsClone.Add(point);
        }

        public void ClearPoints()
        {
            Points.Clear();
            PointsClone.Clear();
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            var p = PropertyChanged;
            if (p != null)
            {
                p(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

将一个 PolyLine.Points 绑定到 Points,将另一个 PolyLine.Points 绑定到 PointsClone。

它有点难看,因为当您使用 vm.Points.Add(point) 而不是 vm.AddPoint(point) 时它会中断。通过应用适当的封装,您也许可以解决这个问题。

于 2012-01-11T14:35:35.143 回答