none
PropertyGrid Events RRS feed

  • Frage

  • Hallo,

    ich brauche mal Hilfe von ein paar Experten:

    ich habe ein PropertyGrid, mit vielen verschiedenen Merkmalen von mir selbst befüllt und soweit funktionsfähig.

    es geht mir um TestChoice1 (siehe Bild), wenn ich da auf das kleine Bild (mit Pfeil markiert) klicke würde ich das gerne mitkriegen, aber ich finde kein Event dafür.

    mit propertyGrid_Click(object sender, EventArgs e) habe ich es probiert, aber das Event wird nicht aufgerufen.

    Das Merkmal besitzt einen StringConverter und einen UITypeEditor, bzw Klassen die davon abgeleitet sind.

     

     

    Wo und Wie könnte ich dafür ein Event anlegen (falls es keins gibt).

     

    Danke und Gruß

    Lucki87

    Freitag, 20. Januar 2012 14:47

Antworten

  • Hallo Lucki87,

    Ich will es aber so dass das Umschalten von PropertyGrid und ListView passiert, wenn ich auf das kleine Bild klicke.

    Dass dein Szenario von PropertyGrid nicht direkt unterstützt wird, ist dir wahrscheinlich schon klar.

    Das kleine Bildchen, auf dem Du klicken möchtest, ist kein interaktives Steuerelement, sondern nur eine Grafik, die im UITypeEditor.PaintValue-Overridehandler gezeichnet wird. Die meisten Steuerelemente, die zur Gestaltung des PropertyGrid-Controls beitragen, sind als "internal" markiert, und können nur über Reflection ausgelesen werden.

    Aber wo ein Wille ist, ist bekanntlich auch ein Weg. Der folgende Code, soll als Anleitung dienen:

    using System;
    using System.Drawing;
    using System.Reflection;
    using System.Windows.Forms;
    
    namespace PropertyGridItemClickDemo
    {
        public partial class Form1 : Form
        {
            public Form1() {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e) {
                propertyGrid1.SelectedObject = 
                    new Car { Manufacturer = "Volkswagen", 
                              Year = 2012, 
                              Model = "Golf R", 
                              Color = Color.BlueViolet }; ;
            }
        }
    
        public class Car {
            public string Manufacturer { get; set; }
            public int Year { get; set; }
            public string Model { get; set; }
            public Color Color { get; set; }
        }
    
        public class PropertyGridEx : PropertyGrid {
            private dynamic PropertyGridView { get; set; }
    
            protected override void OnControlAdded(ControlEventArgs e)
            {
                if (e.Control.GetType().Name == "PropertyGridView") {
                    this.PropertyGridView = e.Control;
                    Type gridViewType = this.PropertyGridView.GetType();
                    EventInfo eventInfo = gridViewType.GetEvent("Click");
                    eventInfo.AddEventHandler(this.PropertyGridView, new EventHandler(OnClick));
                }
    
                base.OnControlAdded(e);
            }
    
            private void OnClick(object source, EventArgs e) {
    
                if (this.SelectedGridItem.PropertyDescriptor == null)
                    return;
    
                MouseEventArgs ea = e as MouseEventArgs;
                Point hitPoint = ea.Location;
    
                if (this.SelectedGridItem.PropertyDescriptor.DisplayName == "Color") {
                    Type gridviewType = this.PropertyGridView.GetType();
                    PropertyInfo propertyInfo = gridviewType.GetProperty("Edit", BindingFlags.Instance | BindingFlags.NonPublic);
                    TextBox edit = (TextBox)propertyInfo.GetValue(this.PropertyGridView, new object[] { });
                    Rectangle targetRectangle = new Rectangle(new Point(edit.Location.X - 26, edit.Location.Y), new Size(19, 19));
    
                    if (targetRectangle.Contains(hitPoint))
                        MessageBox.Show("Hit!");
                }
            }
        }
    }
    
    

    Da Du ja die UITypeEditor-Ableitung - wenn ich dich richtig verstanden habe - selber geschrieben hast, kannst Du ganz genau die Dimensionen des Zielrechteckes berechnen. Im obigen Code begnüge ich mich mit dem standardmäßig für Farben eingesetzten ColorEditor und verwende Näherungswerte.

    Gruß
    Marcel

    Montag, 23. Januar 2012 20:28
    Moderator

Alle Antworten

  • Willst Du nur bei dieser speziellen Eigenschaft reagieren? Dann könntest Du im SelectedGridItemChanged in den SelectedGridItemChangedEventArgs speziell auf diesen Member filtern.

            private void propertyGrid1_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
            {
                if (e.NewSelection.Label == "TestChoice1")
                {
                    // whatever
                }
            }

    • Bearbeitet Anja Länge Sonntag, 22. Januar 2012 20:38
    Sonntag, 22. Januar 2012 20:38
  • Hallo,

     

    also das was ich machen will ist folgendes:

    wenn ich auf dieses kleine Bild klicke wird das PropertyGrid ausgeschalten und ein ListView erscheint mit größeren Bildern daraus wird eins ausgewählt und die ListView geschlossen und die PropertyGrid wieder eingeschaltet, und der Wert wird aus der ListView entnommen und gesetzt.

     

    Da das Event SelectedGridItemChanged nur aufgerufen wird wenn ich eine andere Eigenschaft wähle bringt mir das nichts.

    Ich weiß halt nicht ob ich das PropertyGrid, bzw. die GridItems dazu so überschreiben kann, das ich das mitbekomme wenn irgendwo auf einem GridItem rumgeklickt wird.

     

    Gruß

    Lucki87

    Montag, 23. Januar 2012 08:24
  • Ich das PropertyGrid, bzw. die GridItems dazu so überschreiben kann, das ich das mitbekomme wenn irgendwo auf einem GridItem rumgeklickt wird.

    Dann willst Du kein Klicken abfangen, sondern einen weiteren UITypeEditor ;-) der Dir ein Enum mit den Bildern liefert.

    http://msdn.microsoft.com/en-us/library/aa302326.aspx
    http://msdn.microsoft.com/en-us/library/aa302334.aspx 


    Montag, 23. Januar 2012 10:19
  • Ne nicht ganz, mit dem UITypeEditor kann ich nur angeben ob ich extra Typen habe wenn ich auf das DropDown drücke bzw die (...) je nachdem was ich angebe.

     

    Ich will es aber so das das Umschalten von PropertyGrid und ListView passiert, wenn ich auf das kleine Bild klicke.

    Montag, 23. Januar 2012 11:59
  • Hallo Lucki87,

    Ich will es aber so dass das Umschalten von PropertyGrid und ListView passiert, wenn ich auf das kleine Bild klicke.

    Dass dein Szenario von PropertyGrid nicht direkt unterstützt wird, ist dir wahrscheinlich schon klar.

    Das kleine Bildchen, auf dem Du klicken möchtest, ist kein interaktives Steuerelement, sondern nur eine Grafik, die im UITypeEditor.PaintValue-Overridehandler gezeichnet wird. Die meisten Steuerelemente, die zur Gestaltung des PropertyGrid-Controls beitragen, sind als "internal" markiert, und können nur über Reflection ausgelesen werden.

    Aber wo ein Wille ist, ist bekanntlich auch ein Weg. Der folgende Code, soll als Anleitung dienen:

    using System;
    using System.Drawing;
    using System.Reflection;
    using System.Windows.Forms;
    
    namespace PropertyGridItemClickDemo
    {
        public partial class Form1 : Form
        {
            public Form1() {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e) {
                propertyGrid1.SelectedObject = 
                    new Car { Manufacturer = "Volkswagen", 
                              Year = 2012, 
                              Model = "Golf R", 
                              Color = Color.BlueViolet }; ;
            }
        }
    
        public class Car {
            public string Manufacturer { get; set; }
            public int Year { get; set; }
            public string Model { get; set; }
            public Color Color { get; set; }
        }
    
        public class PropertyGridEx : PropertyGrid {
            private dynamic PropertyGridView { get; set; }
    
            protected override void OnControlAdded(ControlEventArgs e)
            {
                if (e.Control.GetType().Name == "PropertyGridView") {
                    this.PropertyGridView = e.Control;
                    Type gridViewType = this.PropertyGridView.GetType();
                    EventInfo eventInfo = gridViewType.GetEvent("Click");
                    eventInfo.AddEventHandler(this.PropertyGridView, new EventHandler(OnClick));
                }
    
                base.OnControlAdded(e);
            }
    
            private void OnClick(object source, EventArgs e) {
    
                if (this.SelectedGridItem.PropertyDescriptor == null)
                    return;
    
                MouseEventArgs ea = e as MouseEventArgs;
                Point hitPoint = ea.Location;
    
                if (this.SelectedGridItem.PropertyDescriptor.DisplayName == "Color") {
                    Type gridviewType = this.PropertyGridView.GetType();
                    PropertyInfo propertyInfo = gridviewType.GetProperty("Edit", BindingFlags.Instance | BindingFlags.NonPublic);
                    TextBox edit = (TextBox)propertyInfo.GetValue(this.PropertyGridView, new object[] { });
                    Rectangle targetRectangle = new Rectangle(new Point(edit.Location.X - 26, edit.Location.Y), new Size(19, 19));
    
                    if (targetRectangle.Contains(hitPoint))
                        MessageBox.Show("Hit!");
                }
            }
        }
    }
    
    

    Da Du ja die UITypeEditor-Ableitung - wenn ich dich richtig verstanden habe - selber geschrieben hast, kannst Du ganz genau die Dimensionen des Zielrechteckes berechnen. Im obigen Code begnüge ich mich mit dem standardmäßig für Farben eingesetzten ColorEditor und verwende Näherungswerte.

    Gruß
    Marcel

    Montag, 23. Januar 2012 20:28
    Moderator
  • Hallo Marcel,

     

    Danke für deine Antwort. Das bringt mich einiges weiter, aber eine Frage hätte ich noch, ist das auch in .Net Framework 3.5 umsetztbar ?

     

    Gruß

    Lucki87

    Dienstag, 24. Januar 2012 09:45
  • Hallo Lucki87,

    Lass dich nicht vom "dynamic" in die Irre führen, du kannst genausogut "object" nehmen. Dann gibt's auch keine Probleme beim Kompilieren für das .NET Framework 3.5

    Gruß
    Marcel

    Dienstag, 24. Januar 2012 09:49
    Moderator
  • Dankeschön, funktioniert wie gewollt :)

    Vielen lieben Dank

    Dienstag, 24. Januar 2012 09:56