Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PropertyGrid control - modify the position of the central splitting vertical line

I have a PropertyGrid control in WinForms (http://msdn.microsoft.com/en-us/library/aa302326.aspx). Now I want to move the middle vertical line more to the left (It is always centered, but my keys are very short, while the values are Paths, which are long. The control places the line in the middle by default, eventhough the user can move it. In respect to user friendlyness, I would like to move the line more to the left programmatically. I have now searched both the WinForms designer properties as well as the members of the PropertyGrid control multiple times and have not found the option (nor any events concerning it).

Is it hidden from sight/modification by being private? Have I simply overseen it? (In that case, I am sincerely sorry) or how can I do this otherwise?

like image 640
CBenni Avatar asked Jan 27 '13 18:01

CBenni


1 Answers

Yes, unfortunately this requires some reflection based hacks in order to be achieved. Here is a sample extensions class:

PropertyGridExtensionHacks.cs

using System.Reflection;
using System.Windows.Forms;

namespace PropertyGridExtensionHacks
{
    public static class PropertyGridExtensions
    {
        /// <summary>
        /// Gets the (private) PropertyGridView instance.
        /// </summary>
        /// <param name="propertyGrid">The property grid.</param>
        /// <returns>The PropertyGridView instance.</returns>
        private static object GetPropertyGridView(PropertyGrid propertyGrid)
        { 
            //private PropertyGridView GetPropertyGridView();
            //PropertyGridView is an internal class...
            MethodInfo methodInfo = typeof(PropertyGrid).GetMethod("GetPropertyGridView", BindingFlags.NonPublic | BindingFlags.Instance);
            return methodInfo.Invoke(propertyGrid, new object[] {});
        }

        /// <summary>
        /// Gets the width of the left column.
        /// </summary>
        /// <param name="propertyGrid">The property grid.</param>
        /// <returns>
        /// The width of the left column.
        /// </returns>
        public static int GetInternalLabelWidth(this PropertyGrid propertyGrid)
        {
            //System.Windows.Forms.PropertyGridInternal.PropertyGridView
            object gridView = GetPropertyGridView(propertyGrid);

            //protected int InternalLabelWidth
            PropertyInfo propInfo = gridView.GetType().GetProperty("InternalLabelWidth", BindingFlags.NonPublic | BindingFlags.Instance);
            return (int)propInfo.GetValue(gridView);
        }

        /// <summary>
        /// Moves the splitter to the supplied horizontal position.
        /// </summary>
        /// <param name="propertyGrid">The property grid.</param>
        /// <param name="xpos">The horizontal position.</param>
        public static void MoveSplitterTo(this PropertyGrid propertyGrid, int xpos)
        {
            //System.Windows.Forms.PropertyGridInternal.PropertyGridView
            object gridView = GetPropertyGridView(propertyGrid);

            //private void MoveSplitterTo(int xpos);
            MethodInfo methodInfo = gridView.GetType().GetMethod("MoveSplitterTo", BindingFlags.NonPublic | BindingFlags.Instance);
            methodInfo.Invoke(gridView, new object[] { xpos });
        }
    }
}

To move the splitter position use the MoveSplitterTo extension method. Use the GetInternalLabelWidth extension method to get the actual position of the splitter. Please note that I observed that until the SelectedObject is assigned and the PropertyGrid was not shown, GetInternalLabelWidth returns (-1).

Sample use:

using PropertyGridExtensionHacks;
//...

    private void buttonMoveSplitter_Click(object sender, EventArgs e)
    {
        int splitterPosition = this.propertyGrid1.GetInternalLabelWidth();
        this.propertyGrid1.MoveSplitterTo(splitterPosition + 10);
    }
like image 93
Catalin M. Avatar answered Oct 02 '22 08:10

Catalin M.