1

MVVMでSilverlight 5を使用しています。

Singletonである ViewModel があります。ViewModel は、ビューの 1 つでPointCollectionを描画するために使用している を公開しPolylineます。

Polyline2 番目のビューで同じものを描画しようとすると、PointCollection再度データバインドして、「値が期待される範囲内にありません」という例外が発生します。

私が知る限り (Silverlight の限られた知識で)、これはPointCollections共有できないという事実が原因です。

回避策はありますか? 最初のポリラインと同一の 2 番目のポリラインを描画するにはどうすればよいですか? 2 つのポリラインを 1 つの 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 への 2 回目のバインディング

あなたが詳細をほとんど教えてくれなかったので、何が起こっているのかよくわかりませんが、これらの投稿が役立つかもしれません. そうでない場合は、コードを投稿してください。

私はいくつかのテストを行いましたが、私が考えることができる最良の解決策はこれです:

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

1 つの PolyLine.Points を Points にバインドし、もう 1 つの PolyLine.Points を PointsClone にバインドします。

vm.AddPoint(point) の代わりに vm.Points.Add(point) を使用すると壊れるので、少し醜いです。適切なカプセル化を適用することで、それを解決できる場合があります。

于 2012-01-11T14:35:35.143 に答える