PropertyGrid

G

Guest

Is there a way to programmatically set the location of the PropertyGrid's
splitter bar.
Often there is too much white space to the right of my property titles and I
would like to be able to move the splitter bar over.
 
G

Gabriel Lozano-Morán

private void MoveSplitter(PropertyGrid propertyGrid, int x)
{
object propertyGridView =
typeof(PropertyGrid).InvokeMember("gridView", BindingFlags.GetField |
BindingFlags.NonPublic | BindingFlags.Instance, null, propertyGrid, null);
propertyGridView.GetType().InvokeMember("MoveSplitterTo",
BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
null, propertyGridView, new object[] { x });
}

Eg:
MoveSplitter(myPropertyGrid, 100);

Gabriel Lozano-Morán
Real Software
 
G

Guest

Thanks Gabriel! This will work -- I should probably wrap calls to this
function with a try-catch statement in case Microsoft changes the underlying
implementation since the PropertyGridView's MoveSplitterTo method is private
and therefore more susceptible to change. I guess as you've shown, with
introspection nothing is truly private...
 
G

Guest

For what it's worth -- with the code that Gabriel sent for moving the
PropertyGrid
splitter I wrote a function that uses it in the following
PropertyGridManipulator
class in order to move the splitter bar over to fit the largest displayed name
of the property Grid (assuming you are using the DisplayNameAttribute for
properties of the PropertyGrid.SelectedObject). As I mentioned in the last
reply, the reflection stuff is circumventing privacy of the
PropertyGridView's MoveSplitterTo method, so this code may no longer work in
future versions of framework but the try-catch will prevent a crash.

<code>
public class PropertyGridManipulator
{
public static void MoveSplitter(PropertyGrid propertyGrid, int x)
{
object propertyGridView =
typeof(PropertyGrid).InvokeMember("gridView",
BindingFlags.GetField |
BindingFlags.NonPublic |
BindingFlags.Instance, null, propertyGrid, null);

propertyGridView.GetType().InvokeMember("MoveSplitterTo",

BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
null, propertyGridView,
new object[] { x });
}

/// <summary>
/// Moves the property Grid's splitter bar over to fit the width of
the longest display name string + padding
///
/// </summary>
/// <param name="propertyGrid">The property Grid whose splitter bar
is to be moved</param>
/// <param name="iPadding">Right padding to include with longest
display name width</param>
public static void MoveSplitterToLongestDisplayName(PropertyGrid
propertyGrid, int iPadding)
{
try
{

Type pgObjectType = propertyGrid.SelectedObject.GetType();
string longestDisplayName = "";
// Iterate through all the properties of the class.
foreach (PropertyInfo mInfo in pgObjectType.GetProperties())
{
// Iterate through all the Attributes for each property.
foreach (Attribute attr in

mInfo.GetCustomAttributes(typeof(DisplayNameAttribute), false))
{
// Check for the AnimalType attribute.
if (attr.GetType() == typeof(DisplayNameAttribute))
{
DisplayNameAttribute displayNameAttr =
(DisplayNameAttribute)attr;
if (displayNameAttr.DisplayName.Length >
longestDisplayName.Length)
{
longestDisplayName =
displayNameAttr.DisplayName;
}
}
}

}

Size textSize = TextRenderer.MeasureText(longestDisplayName,
propertyGrid.Font);
PropertyGridManipulator.MoveSplitter(propertyGrid,
textSize.Width + iPadding);
}
catch (Exception exception1)
{
MessageBox.Show(exception1.Message);
//do nothing for now --
//if exception was thrown the private method MoveSplitterTo
//of the C# version 2.0 framework's PropertyGrid's
//PropertyGridView probably is no
//longer named the same or has a different
//method signature in the current C# framework
}
}//end public static void
MoveSplitterToLongestDisplayName(PropertyGrid propertyGrid, int iPadding)
}

</code>
 
?

=?ISO-8859-15?Q?Stefan_Br=FCggemann?=

Gabriel said:
private void MoveSplitter(PropertyGrid propertyGrid, int x)
{
object propertyGridView =
typeof(PropertyGrid).InvokeMember("gridView", BindingFlags.GetField |
BindingFlags.NonPublic | BindingFlags.Instance, null, propertyGrid, null);
propertyGridView.GetType().InvokeMember("MoveSplitterTo",
BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
null, propertyGridView, new object[] { x });
}

Eg:
MoveSplitter(myPropertyGrid, 100);

Hello, i tried this, but it doesn't work.
The Splitter always moves, but always to the same location.
I tried to pass values for x from -1000 to 1000, but it doesn't
have any effect.
My PropertyGrid has no categories, no help, no toolbar, just a few
properties. And I want to move the splitter :)

Any Ideas? .NET 2.0 ?

Thanks in Advance,

Stefan Brüggemann
 
M

martinfrompi

Stefan said:
Gabriel said:
private void MoveSplitter(PropertyGrid propertyGrid, int x)
{
object propertyGridView =
typeof(PropertyGrid).InvokeMember("gridView", BindingFlags.GetField |
BindingFlags.NonPublic | BindingFlags.Instance, null, propertyGrid, null);
propertyGridView.GetType().InvokeMember("MoveSplitterTo",
BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
null, propertyGridView, new object[] { x });
}

Eg:
MoveSplitter(myPropertyGrid, 100);

Hello, i tried this, but it doesn't work.
The Splitter always moves, but always to the same location.
I tried to pass values for x from -1000 to 1000, but it doesn't
have any effect.
My PropertyGrid has no categories, no help, no toolbar, just a few
properties. And I want to move the splitter :)

Any Ideas? .NET 2.0 ?
Well b****r me!

I've just posted a "How do I do that" question, and you bring this
ancient thread to the top by replying to it!

Since my post, I've found that those nice people at NDoc have written a
class called "RuntimePropertyGrid" with (among other things) :
/// <summary>
/// Gets or sets the width of the label.
/// </summary>
/// <value></value>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int LabelWidth
{
get
{
Type type = this.GetType().BaseType;
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public |
BindingFlags.NonPublic;
FieldInfo field = type.GetField("gridView", flags);
object gridView = field.GetValue(this);
type = gridView.GetType();
PropertyInfo prop = type.GetProperty("InternalLabelWidth", flags);
object InternalLabelWidth =
prop.GetValue(gridView,BindingFlags.GetProperty,null,null,null);
return (int)InternalLabelWidth;
}
set
{
Type type = this.GetType().BaseType;
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public |
BindingFlags.NonPublic;
FieldInfo field = type.GetField("gridView", flags);
object gridView = field.GetValue(this);
type = gridView.GetType();
MethodInfo method = type.GetMethod("MoveSplitterTo",flags);
method.Invoke(gridView,new Object[]{value});
}
}

It looks very similar, but I don't know if it is different enough to
make it work again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top