Question CustomPropertyGrid with CustomCollectionEditor - Detecting a change in the collection

tim8w

Well-known member
Joined
Sep 8, 2020
Messages
129
Programming Experience
10+
I have a CustomePropertyGrid with a CustomCollectionEditor. From within the CustomCollectionEditor, I can detect when the OK or Cancel button is clicked. I have tried almost every relevant event from the PropertyGrid documentation and it appears that apparently there is no event fired for PropertyGrid to let me know that the OK button in the CollectionEditor happened. How do I detect this?
 
I've never done what you're doing so I don't know the details of how it's usually done but I would assume you are calling CreateCollectionForm and then calling ShowDialog on that form. That method will return a result that indicates which button was clicked and you can do whatever you want with that. If you are creating custom classes then you can add your own custom event and raise it when ShowDialog returns DialogResult.OK. As you have provided no relevant code, I have only been able to rely on the results of some very quick research, so I'm not sure whether there is some specific reason that this suggestion wouldn't work.
 
I CAN detect it from within the CollectionEditor, but I need someway for it to be detected from the main form where the PropertyGrid is defined. I have checked all the relevant documentation on PropertyGrid and it appears not to have any way to detect any changes in the collection it hosts. I will post the relevant code here:

Main form PropertyGrid assignment. This is where I want to know if the Collection changed.

DefectPropertyGrid.SelectedObject = new FirstPassYield.PropertyGridItems();:
DefectPropertyGrid.SelectedObject = new FirstPassYield.PropertyGridItems();


Definition of PropertyGridItems:

C#:
    internal class PropertyGridItems
    {
        private DefectCollection _Defects = new DefectCollection();

        [Editor(typeof(FirstPassYield.MyCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
        [Category("Defects")]
        [DisplayName("Add Defects")]
        [Description("Click on the Collection elipsis (...) to add the defects found for this WO Number.")]
        public DefectCollection Defects
        {
            get { return _Defects; }
            set { _Defects = value; }
        }
    }

Definition of MyCollectionEditor:

C#:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using System.ComponentModel.Design;
using System.Windows.Forms;

namespace FirstPassYield
{
    public class MyCollectionEditor : CollectionEditor
    {
        public static bool bEditingCollection = false;

        public delegate void MyFormClosedEventHandler(object sender, FormClosedEventArgs e);

        //public event MyFormClosedEventHandler MyFormClosed;

        public delegate void MyFormLoadEventHandler(object sender, System.EventArgs e);

        //public event MyFormLoadEventHandler MyFormLoad;


        public delegate void MyFormControlAddedEventHandler(object sender, System.EventArgs e);

        //public event MyFormControlAddedEventHandler MyFormControlAdded;

        public MyCollectionEditor(Type type)
            : base(type)
        {
        }

        protected override string GetDisplayText(object value)
        {
            Defect item = new Defect();
            item = (FirstPassYield.Defect)value;

            if (String.IsNullOrEmpty(item.DefectCode))
                return base.GetDisplayText(" ");
            else
            {
                String sDisplay = item.DefectCode.ToString().Substring(0, item.DefectCode.ToString().IndexOf(":"));
                return base.GetDisplayText(string.Format("{0}", sDisplay));
            }
        }

        protected override CollectionForm CreateCollectionForm()
        {
            CollectionForm collectionForm = base.CreateCollectionForm();
            Font myDialogFont = new Font("Microsoft San Seraf", 16.0f, FontStyle.Bold); // Form's Font
            Font myFont = new Font("Microsoft San Seraf", 16.0f, FontStyle.Bold);       // Individual Item's Font

            // Set the Dialog Font
            collectionForm.Font = myDialogFont;

            // Turn OFF Help Button
            collectionForm.HelpButton = false;

            // Set the BackColor, StartPosition and Size of the form
            collectionForm.BackColor = Color.FromName("SteelBlue");
            collectionForm.StartPosition = FormStartPosition.CenterParent;
            collectionForm.Size = new Size(1100, 500);

            // Add Form Handlers for trapping Load and Close
            collectionForm.FormClosed += this.collection_FormClosed;
            collectionForm.Load += this.collection_FormLoad;

            var overArchingTableLayoutPanel = collectionForm.Controls["overArchingTableLayoutPanel"];

            // Change the size of the "listbox"
            Size mySize = new Size(200, 337);
            overArchingTableLayoutPanel.Controls["listbox"].Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left;
            overArchingTableLayoutPanel.Controls["listbox"].Size = mySize;

            var addRemoveTableLayoutPanel = overArchingTableLayoutPanel.Controls["addRemoveTableLayoutPanel"];
            // Change the width of the Add/Remove Buttons to match the new "listbox" size
            addRemoveTableLayoutPanel.Controls["addButton"].Anchor = 0;
            addRemoveTableLayoutPanel.Controls["addButton"].Width = addRemoveTableLayoutPanel.Controls["addButton"].Width / 2;
            addRemoveTableLayoutPanel.Controls["removeButton"].Anchor = 0;
            addRemoveTableLayoutPanel.Controls["removeButton"].Width = addRemoveTableLayoutPanel.Controls["removeButton"].Width / 2;
            // Set the BackColor of the Buttons - It appears that they get set by default to the form's BackColor
            addRemoveTableLayoutPanel.Controls["addButton"].BackColor = Color.FromName("Control");
            addRemoveTableLayoutPanel.Controls["removeButton"].BackColor = Color.FromName("Control");
            // Set the Font for the Add, Remove buttons
            addRemoveTableLayoutPanel.Controls["addButton"].Font = myFont;
            addRemoveTableLayoutPanel.Controls["removeButton"].Font = myFont;
            // Add Handlers for trapping Add and Remove Buttons
            addRemoveTableLayoutPanel.Controls["addButton"].Click += AddButton_Click;
            addRemoveTableLayoutPanel.Controls["removeButton"].Click += RemoveButton_Click;

            var okCancelTableLayoutPanel = overArchingTableLayoutPanel.Controls["okCancelTableLayoutPanel"];
            // Set the BackColor of the Buttons - It appears that they get set by default to the form's BackColor
            okCancelTableLayoutPanel.Controls["okButton"].BackColor = Color.FromName("Control");
            okCancelTableLayoutPanel.Controls["cancelButton"].BackColor = Color.FromName("Control");
            // Set the Font for the OK, Cancel buttons
            okCancelTableLayoutPanel.Controls["okButton"].Font = myFont;
            okCancelTableLayoutPanel.Controls["cancelButton"].Font = myFont;
            // Add Handlers for trapping OK and Cancel Buttons
            okCancelTableLayoutPanel.Controls["okButton"].Click += OKButton_Click;
            okCancelTableLayoutPanel.Controls["cancelButton"].Click += CancelButton_Click;

            // Change the Member Labels' Text, Color and Font
            overArchingTableLayoutPanel.Controls["membersLabel"].Text = "&Defect List:";
            overArchingTableLayoutPanel.Controls["membersLabel"].ForeColor = Color.FromName("White");
            overArchingTableLayoutPanel.Controls["membersLabel"].Font = myFont;
            // Change the Properties Labels' Text, Color and Font
            overArchingTableLayoutPanel.Controls["propertiesLabel"].Text = "&Properties:";
            overArchingTableLayoutPanel.Controls["propertiesLabel"].ForeColor = Color.FromName("White");
            overArchingTableLayoutPanel.Controls["propertiesLabel"].Font = myFont;
            // Set the BackColor of the Buttons - It appears that they get set by default to the form's BackColor
            overArchingTableLayoutPanel.Controls["upButton"].BackColor = Color.FromName("Control");
            overArchingTableLayoutPanel.Controls["downButton"].BackColor = Color.FromName("Control");
            // Add Handlers for trapping Up and Down Buttons
            overArchingTableLayoutPanel.Controls["upButton"].Click += UpButton_Click;
            overArchingTableLayoutPanel.Controls["downButton"].Click += DownButton_Click;

            var propertyBrowser = overArchingTableLayoutPanel.Controls["propertyBrowser"] as PropertyGrid;
            if (propertyBrowser.Controls.Count != 0)
            {
                // Set the PropertySorting and ToolbarVisibilty
                propertyBrowser.PropertySort = PropertySort.NoSort;
                propertyBrowser.ToolbarVisible = false;
            }

            // Do something based on which Collection Editor was called
            switch (collectionForm.Text)
            {
                case "Defect Collection Editor":
                    {
                        break;
                    }
            }

            // Hide Add, Remove, Up and Down Buttons
            //collectionForm.Controls["overArchingTableLayoutPanel"].Controls["addRemoveTableLayoutPanel"].Controls["addButton"].Visible = false;
            //collectionForm.Controls["overArchingTableLayoutPanel"].Controls["addRemoveTableLayoutPanel"].Controls["removeButton"].Visible = false;
            //collectionForm.Controls["overArchingTableLayoutPanel"].Controls["upButton"].Visible = false;
            //collectionForm.Controls["overArchingTableLayoutPanel"].Controls["downButton"].Visible = false;

            return collectionForm;
        }

        private void collection_FormLoad(object sender, System.EventArgs e)
        {
            bEditingCollection = true;
        }

        private void AddButton_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("Add Button Clicked");
        }

        private void RemoveButton_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("Remove Button Clicked");
        }

        private void OKButton_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("OK Button Clicked");
            FirstPassYield.frmFirstPassYield.bCollectionChanged = true;
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("Cancel Button Clicked");
        }

        private void UpButton_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("Up Button Clicked");
        }

        private void DownButton_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("Down Button Clicked");
        }

        private void collection_FormClosed(object sender, FormClosedEventArgs e)
        {
            bEditingCollection = false;
        }
    }
}

As you can see in the the Custom CollectionEditor, I can tell which buttons have been pressed. I really only need to know that OK was pressed, but not here. I need to check a bunch of controls in the main form.
 
Back
Top Bottom