Autor Beitrag
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Fr 27.01.06 17:21 
Hallo!

Ich entwickle eine Komponete, welche Datenpunkte darstellen soll. Ansich klappt das ganz wunderbar, allerdings kämpfe ich mit einer kleinen Unschönheit:

Man kann die linke, obere Ecke und die rechte, untere Ecke des darzustellenden Bereiches angeben. Beide werden als "DataPoint" gespeichert ist, was eine selbst geschriebe Klasse ist, die eigentlich nur einen double x und einen double y enthält.

Hier die Klasse:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
    [TypeConverterAttribute(typeof(DataPointConverter))]
    public class DataPoint
    {
        private double x;

        [NotifyParentProperty(true)]
        public double X
        {
            get { return x; }
            set { x = value; }
        }
        private double y;

        [NotifyParentProperty(true)]
        public double Y
        {
            get { return y; }
            set { y = value; }
        }

        public DataPoint(double X, double Y)
        {
            this.X = X;
            this.Y = Y;
        }

        public DataPoint()
        {
            this.X = 0;
            this.Y = 0;
        }

        public override string ToString()
        {
            return this.X.ToString() + "; " + this.Y.ToString();
        }
    }


Ich habe ausserdem einen entsprechenden Konverter geschrieben:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
    public class DataPointConverter : ExpandableObjectConverter
    {
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(DataPoint))
                return true;

            return base.CanConvertTo(context, destinationType);
        }

        public override object ConvertTo(ITypeDescriptorContext context,
            System.Globalization.CultureInfo culture,
            object value,
            Type destinationType)
        {
            if (destinationType == typeof(System.String) &&
                value is DataPoint)
            {
                return ((DataPoint)value).ToString();
            }

           return base.ConvertTo(context, culture, value, destinationType);
        }

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(System.String))
                return true;

           return base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context,
            System.Globalization.CultureInfo culture,
            object value)
        {
            if (value is string)
            {
                try{
                    string s = (string)value;
                    string[] parts = s.Split(new char[] {';'});
                    
                    DataPoint dp = new DataPoint();
                    dp.X = Double.Parse(parts[0].Trim());
                    dp.Y = Double.Parse(parts[1].Trim());
                    return dp;
                }
                catch
                {
                    throw new ArgumentException("Cannot convert!");
                }
            }
           return base.ConvertFrom(context, culture, value);
        }
    }


Die entsprechenden Punkte sind so deklariert:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
        private DataPoint topLeft;
        [Category("Plot Settings")]
        public DataPoint TopLeft
        {
            get { return topLeft; }
            set {
                topLeft = value;
                OutputData();
                if (TopLeftChanged != null)
                    TopLeftChanged(thisnew PropertyChangedEventArgs("TopLeft"));
            }
        }
        [Category("Property Changed")]
        public event PropertyChangedEventHandler TopLeftChanged;

Analog bottomRight.

Im Properties-Tab werden die Punkte auch korrekt angezeigt (also "aufklappbar", sodass man x und y getrennt eingeben kann). Leider bemerkt die Komponente es nicht, wenn ich x oder y ändere, obwohl "NotifyParentProperty" das bewirken sollte. Ändere ich den Wert nicht separat, sondern ändere den String, welcher TopLeft vollständig darstellt (z.B. "4.0; 5.0"), wird die Änderung bemerkt.

Wie kann ich das Problem lösen?

Grüße
Christian

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Christian S. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Sa 28.01.06 15:29 
Habe die Lösung gefunden. Man muss die Klasse "DataPointConverter" um folgendes erweitern:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
        public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
        {
            return new DataPoint((double)propertyValues["X"], (double)propertyValues["Y"]);            
        }


Quelle: www.windowsitlibrary...ntent/1085/09/3.html

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".