Domanda

sto usando Silverlight 5 con MVVM.

Ho un ViewModel che è un Singleton . Il ViewModel espone una PointCollection che sto usando per disegnare un Polyline in uno dei miei punti di vista.

Se provo a disegnare la stessa Polyline in una seconda vista, dalla associazione dati al PointCollection ancora una volta, ottengo un "valore non rientra nel range previsto" eccezione.

Per quanto ho potuto scoprire (con la mia conoscenza Silverlight limitato), questo è causato dal fatto che PointCollections non sono condivisibili.

C'è una soluzione? Come posso ottenere una seconda polilinea attratta che è identico al primo? Voglio databind due Polilinee ad uno PointCollection , allo stesso tempo.

Edit: non ho trovato una soluzione, ma qualcuno con lo stesso problema qui . Secondo Microsoft:

Questa pagina MSDN menziona che alcuni oggetti non sono condivisibili e sarà genereate un "valore fuori portata" eccezione. http://msdn.microsoft.com/en-us/library/system.windows.resourcedictionary(VS.95).aspx

La pagina PointCollection menziona anche che non è condivisibile. http://msdn.microsoft.com/en-us/library/system.windows.media.pointcollection(VS.95).aspx

Al momento, questo è di un comportamento di progettazione. Tuttavia, stiamo valutando questo per vedere se siamo in grado di modificare il comportamento sia o almeno il testo eccezione.

È stato utile?

Soluzione

Have a look at this question: Why doesn't this data binding work?

And at this one too: 2nd time binding to PointCollection not being rendered

As you gave little details I am not quite sure what is going on but these posts might help out. If not, please post your code.

I did some testing and the best solution I can think of is this:

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

Bind one PolyLine.Points to Points and the other PolyLine.Points to PointsClone.

It is a bit ugly because it will break when you use vm.Points.Add(point) instead of vm.AddPoint(point). By applying proper encapsulation you might be able to solve that.

Altri suggerimenti

I found a solution here: duplicate the PointCollection in the getter.

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

Maybe your PointCollection is Freezed and that's making the trouble.

MSDN:

Freezable Features: Because it inherits from the Freezable class, the PointCollection class provides several special features: PointCollection objects can be declared as resources, shared among multiple objects, made read-only to improve performance, cloned, and made thread-safe. For more information about the different features provided by Freezable objects, see the Freezable Objects Overview.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top