I have written this code in visual studio 2013 utilizing .net v4.5. The problem I am having is that I am now having to drop down to .net v3.5 and the dynamic keyword is throwing an error as missing an assembly reference. Is there an equivalent type to 'dynamic' in .net v3.5 or a way for me to achieve the same results as below?
I thought I may have found my answer here, but var is throwing errors when I add the .Attributes or .Text property modifications.
private void CreateControl<T>(string objText,
Panel pnl,
string HTMLTag = "<td>",
string applicantID = "",
EventHandler hndl = null)
{
pnl.Controls.Add(new LiteralControl(HTMLTag));
dynamic obj = Activator.CreateInstance(typeof(T));
obj.Text = objText;
if (applicantID != string.Empty)
{
obj.Attributes.Add("ApplicantID", applicantID);
}
if (hndl != null)
{
obj.Click += new EventHandler(hndl);
}
pnl.Controls.Add(obj);
pnl.Controls.Add(new LiteralControl(HTMLTag.Insert(1, "/")));
}
Instead of trying to hack this together in some bound to fail way and since there isn't a 'dynamic' control in .net v3.5, I have instead decided to just completely forgo this method and wrote some overloads instead. This way seems safer at this point; works the same, just a bit more code...
#region CreateControl() Overloads
/// <summary>
/// Creates a LinkButton control.
/// </summary>
/// <param name="objText">.Text property of this LinkButton control.</param>
/// <param name="pnl">Panel this control will be attached to.</param>
/// <param name="hndl">Event handler attached to this LinkButton control.</param>
/// <param name="HTMLTag">Opening tag used to contain this control.</param>
private void CreateControl(string objText,
Panel pnl,
EventHandler hndl,
string HTMLTag)
{
pnl.Controls.Add(new LiteralControl(HTMLTag));
LinkButton obj = new LinkButton();
obj.Text = objText;
obj.Click += new EventHandler(hndl);
pnl.Controls.Add(obj);
pnl.Controls.Add(new LiteralControl(HTMLTag.Insert(1, "/")));
}
/// <summary>
/// Creates a Label control.
/// </summary>
/// <param name="objText">.Text property of this Label control.</param>
/// <param name="pnl">Panel this control will be attached to.</param>
/// <param name="HTMLTag">Opening tag used to contain this control.</param>
private void CreateControl(string objText,
Panel pnl,
string HTMLTag)
{
pnl.Controls.Add(new LiteralControl(HTMLTag));
Label obj = new Label();
obj.Text = objText;
pnl.Controls.Add(obj);
pnl.Controls.Add(new LiteralControl(HTMLTag.Insert(1, "/")));
}
/// <summary>
/// Creates the specified literal control.
/// </summary>
/// <param name="ControlText">HTML text containing instructions for creating the desired literal control.</param>
/// <param name="pnl">Panel this literal control will be attached to.</param>
private void CreateControl(string ControlText,
Panel pnl)
{
pnl.Controls.Add(new LiteralControl(ControlText));
}
#endregion
Is there an equivalent type to 'dynamic' in .net v3.5
No. dynamic requires .NET 4.0.
or a way for me to achieve the same results as below?
You could use reflection instead of dynamic to create the control and add your event handlers.
However, since this appears to be one of a few custom controls you're creating (given the attributes, etc), you may be able to constrain to an interface or base class, which would allow you to create the items and use those shared properties directly.
Based on your code, it looks like you're writing a generic method to pass in some unknown controls and attach them to a panel.
It also looks like you're dealing with different types of controls; i.e., not all WebControls have Text, and Attributes, AND Click properties;
This is a bit hacky but works in 3.5 - you can just use casting of the various underlying types or interfaces to access the needed properties, something like this:
private void CreateControl<T>(string objText, Panel pnl, string HTMLTag,
string applicantID, EventHandler hndl)
where T : Control, new()
{
pnl.Controls.Add(new LiteralControl(HTMLTag));
T obj = new T();
if (obj is ITextControl) (obj as ITextControl).Text = objText;
if (applicantID != string.Empty && obj is WebControl)
(obj as WebControl).Attributes.Add("ApplicantID", applicantID);
if (obj is IButtonControl)
{
(obj as IButtonControl).Text = objText;
if (hndl != null)
{
(obj as IButtonControl).Click += new EventHandler(hndl);
}
}
pnl.Controls.Add(obj as Control);
pnl.Controls.Add(new LiteralControl(HTMLTag.Insert(1, "/")));
}
Test code:
protected void Page_Load(object sender, EventArgs e)
{
var panel = new Panel();
CreateControl<Button>("test", panel, "<td>", "123", (s, args) => Console.WriteLine("hello!"));
CreateControl<Label>("test", panel, "<td>", "123", (s, args) => Console.WriteLine("hello!"));
CreateControl<Panel>("test", panel, "<td>", "123", (s, args) => Console.WriteLine("hello!"));
CreateControl<Literal>("test", panel, "<td>", "123", (s, args) => Console.WriteLine("hello!"));
//This won't compile because object doesn't fit <control> constraint
//CreateControl<object>("test", panel, "<td>", "123", (s, args) => Console.WriteLine("hello!"));
}
To be honest I'm not 100% sure I like this approach. I might use some more specific methods and possibly method overloading to get more specific with different types of control creation, but this may help point you in the right direction.
Note that optional parameters are also not yet "invented" in C# 3.0 which shipped with .net 3.5, so you have to actually pass in all of the values.
dynamic keyword is available on .net 4.x and is a simple way to store any kind of value, it just resolve his type in runtime. It has been useful to me working with JSON strings.
string jsonValue = "{name:'Pedro',lastName:'Mora'}";
dynamic Variable = new JavascriptSerializer().Deserialize<dynamic>(jsonValue);
return Variable.name;
//It will return "Pedro"
Thing is that you have to be sure that the value won't be null and the properties or attributes or methods or something refered to the object exists and it takes it's values on runtime.
Related
I am trying to reuse NumberBoxes for a GridView because having the NumberBoxes embedded directly in the GridView data template causes undesirable behavior, while reusing them does not. The problem is that I keep getting exceptions. They say "No installed components were detected" on the following line (templateRoot.FindName("NumberBox") as GridViewItem).Content = item.NumberBox; in this context
/// <summary>
/// The callback for updating a container in the GridView named CardGridView.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void UpdateGridViewContainer(ListViewBase sender, ContainerContentChangingEventArgs args)
{
if (args.Phase == 1)
{
Grid templateRoot = args.ItemContainer.ContentTemplateRoot as Grid;
CardItem item = args.Item as CardItem;
(templateRoot.FindName("NumberBox") as GridViewItem).Content = item.NumberBox;
TypedEventHandler<NumberBox, NumberBoxValueChangedEventArgs> handler =
(box, args) =>
{
if (!double.IsNaN(args.NewValue))
{
_viewModel.ChangeCount(args, item);
}
};
item.SetHandler(handler);
}
}
The exception is thrown when the Page that contains the GridView is left and renavigated to. I have tried nulling out the NumberBoxes when the page is left, but that did not work. Well, it appeared to before the issue cropped up again.
This is the code that nulls out the NumberBoxes
/// <summary>
/// Creates new NumberBoxes for when this Page is loaded again.
/// </summary>
private void ResetNumberBoxes()
{
foreach (CardItem card in CardGridView.Items.Cast<CardItem>())
{
card.ResetNumberBox();
}
CardGridView.ItemsSource = null;
CardGridView.Items.Clear();
}
ResetNumberBox is just setting the NumberBox to null and assigning a new one.
The exception details
System.Runtime.InteropServices.COMException
HResult=0x800F1000
Message=No installed components were detected. (0x800F1000)
Source=WinRT.Runtime
StackTrace:
at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|20_0(Int32 hr)
at ABI.Microsoft.UI.Xaml.Controls.IContentControlMethods.set_Content(IObjectReference _obj, Object value)
An update. I have removed the GridViewItem control from the DataTemplate and tried doing the following with the same result
CardItem item = args.Item as CardItem;
Grid.SetColumn(item.NumberBox, 1);
item.NumberBox.HorizontalAlignment = HorizontalAlignment.Center;
item.NumberBox.VerticalAlignment = VerticalAlignment.Center;
(templateRoot.FindName("GridViewTemplate") as Grid).Children.Add(item.NumberBox);
I also examined a heap dump right before the line that throws, and there was only one instance of the Grid, and the NumberBox had a parent of null.
I making an app, where I like writte some bytes into textbox. I like to validate if real HEX code is written into textbox or not and remind user if not.
I never made this in MVVM and XAML. How to do it? I find several tutorial on web, but problem is that I like to write 64 bytes. I have 64 textboxes pull together in one array.
One of the textbox:
<TextBox Text="{Binding TB[4], UpdateSourceTrigger=PropertyChanged}" Grid.Column="0" Grid.Row="0" Style="{StaticResource byteTextBoxStyle}"/>
and array variable:
private string[] _tb = new string[64];
public string[] TB
{
get
{ return _tb; }
set
{
_tb = value;
NotifyPropertyChanged("TB");
}
}
Goal is that red textblock is under of all textboxes and write a red (Something like that).
I can do it later when button is pressed - pull together array in to one string and check with regex is something is not OK. But I want this in real time, when user put-in text and right away recognite if is OK or not.
Please for help, because I am new in MVVM and WPF thing. If any question please ask. Thanks!
I have done something similar in the past using System.Windows.Interactivity.dll
https://www.nuget.org/packages/System.Windows.Interactivity.WPF/
All it does is terminate the key down event if a non hex value is keyed in.
{
/// <summary>
/// Provides functionality to allow users to type only letters [0-9 A-F a-f].
/// </summary>
public class HexEditTextBox : TriggerAction<DependencyObject>
{
protected override void Invoke(object parameter)
{
var textBox = this.AssociatedObject as TextBox;
if (textBox != null) textBox.PreviewKeyDown += HandlePreviewKeyDownEvent;
}
/// <summary>
/// Checks whether the input is a valid key for a Hex number.
/// Sets the 'Handled' Property as True if the input is invalid, so that further actions will not be performed for this Action.
/// </summary>
/// <param name="sender"></param>
/// <param name="e">KeyEventArgs instance</param>
private void HandlePreviewKeyDownEvent(object sender, KeyEventArgs e)
{
var acceptedKeys = new List<Key>()
{
Key.D0, Key.D1, Key.D2, Key.D3,Key.D4,Key.D5,Key.D6,Key.D7,Key.D8,Key.D9,
Key.A,Key.B,Key.C,Key.D,Key.E,Key.F,
Key.Tab,Key.Back,Key.Delete,Key.Left,Key.Right,Key.Up,Key.Down,Key.Enter,Key.Home,Key.End,
Key.NumPad0,Key.NumPad1,Key.NumPad2,Key.NumPad3,Key.NumPad4,Key.NumPad5,Key.NumPad6,Key.NumPad7,Key.NumPad8,Key.NumPad9
};
e.Handled = !acceptedKeys.Contains(e.Key);
}
}
}
You should be able to insert your validation here.
I've been working on an application months ago, my friend and i wanted to share this application with other friends, and i need to display some help to make the application easier because it was designed only for both of us.
The idea that came out is to display help on a text Block every time a hover event is popped from a button. So we added a textBlock. Now the problem that we still facing is how to create the Hover Event for every button in our Main Window, there are a lots of buttons in this window, So we can't add an event to every button in the XAML code.
What i am expecting from this answer is a way to add Hover Event to all buttons in the main window Programmatically ?
EDIT: after some googling and help, i can do the following :
foreach (UIElement btn in GeneralMenuGrid.Children)
{
if (btn is Button)
{
Button currentButton = (Button)btn;
currentButton.Content = "test";
}
}
This is just a test that will allow all the buttons in the GeneralMenuGrid control to have a content : test, now the problem again is that i have nested controls in this grid, how can i reach them?
EDIT : after years of goggling i got to loop through all the buttons in my window with this :
public static void EnumVisuals(Visual argVisual, Window currentWindow)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(argVisual); i++)
{
Visual childVisual = (Visual) VisualTreeHelper.GetChild(argVisual, i);
if (childVisual is Button)
{
var button = childVisual as Button;
button.MouseEnter += AllButtonsOnMouseEnter;
}
EnumVisuals(childVisual, currentWindow);
}
}
now in the AllButtonsOnMouseEnter function, i can't access a button, i made it public... i can't access it from this class, how can i send the window with the event arguments?
You wrote, "there are a lots of buttons in this window, so we can't add an event to every button in the XAML code." But you can - just add a style that applies to all buttons:
<Style TargetType="{x:Type Button}">
<EventSetter Event="MouseEnter" Handler="Button_MouseEnter"/>
</Style>
I don't know how you intend to get the help text relevant to each Button, but it's easy to store it in the Button's Tag:
<Button Tag="Instantly move from one place to another.">
Teleport
</Button>
Then write an event handler that shows the help in your TextBlock:
private void Button_MouseEnter(object sender, MouseEventArgs e)
{
Button button = sender as Button;
textblock_that_shows_help.Text = button.Tag;
}
I've created an extension method that does this, adapted from here: Find all controls in WPF Window by type
Put this class somewhere in your project:
public static class VisualTreeSearch
{
/// <summary>
/// Finds all elements of the specified type in the <see cref="System.Windows.DependencyObject"/>'s visual tree using a breadth-first search.
/// </summary>
/// <typeparam name="T">The type of element to search for.</typeparam>
/// <param name="root">The object to search in.</param>
/// <returns>A list of elements that match the criteria.</returns>
public static IEnumerable<T> Find<T>(this DependencyObject root) where T : DependencyObject
{
return root.Find<T>(false, true);
}
/// <summary>
/// Finds all elements of the specified type in the <see cref="System.Windows.DependencyObject"/>'s visual tree.
/// </summary>
/// <typeparam name="T">The type of element to search for.</typeparam>
/// <param name="root">The object to search in.</param>
/// <param name="depthFirst">True to do a depth-first search; false to do a breadth-first search</param>
/// <param name="includeRoot">True to include the root element in the search; false to exclude it</param>
/// <returns>A list of elements that match the criteria.</returns>
public static IEnumerable<T> Find<T>(this DependencyObject root, bool depthFirst, bool includeRoot) where T : DependencyObject
{
if (includeRoot)
{
var depRoot = root as T;
if (depRoot != null)
yield return depRoot;
}
var searchObjects = new LinkedList<DependencyObject>();
searchObjects.AddFirst(root);
while (searchObjects.First != null)
{
var parent = searchObjects.First.Value;
var count = VisualTreeHelper.GetChildrenCount(parent);
var insertAfterNode = depthFirst ? searchObjects.First : searchObjects.Last;
for (int i = 0; i < count; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
var depChild = child as T;
if (depChild != null)
yield return depChild;
insertAfterNode = searchObjects.AddAfter(insertAfterNode, child);
}
searchObjects.RemoveFirst();
}
}
}
To use the extension method, write the following in your window class (as an example). This code loops through all children, grandchildren, etc. of this (which should be your Window in this case) and finds all Button elements.
foreach (var button in this.Find<Button>())
{
button.MouseEnter += button_MouseEnter;
}
...
private void button_MouseEnter(object sender, MouseEventArgs e)
{
// Do stuff
}
after a lot of googling and chat help... i finally did it, maybe other will be interested this is how i proceeded :
i created a static recursive function that will get all the buttons in the window:
public static void EnumVisuals(Visual argVisual, Button toModifyButton)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(argVisual); i++)
{
Visual childVisual = (Visual) VisualTreeHelper.GetChild(argVisual, i);
if (childVisual is Button)
{
var button = childVisual as Button;
button.MouseEnter += (sender, eventArgs) =>
{
toModifyButton.Content = "Get the Help text from database if you want";
};
}
EnumVisuals(childVisual, toModifyButton);
}
}
why do you send a Button :
i need to write the help in a button, and the only way i found to access it's content property is to send it via this function and of course make it public.
Hope you'll find this helpfull.
I have a situation where I have several (let's say 10 for now) DevExpress LookUpEdit controls (sort of like DropDown Controls for Windows) on several tabs on my form. All 10 of these controls are the same in that they use the same data source to get their information from. What I'm trying to do is if a value changes in ANY of the 10 controls, then I want it to change in the other 9 controls as well. Because I have other controls of this type on my form that I do not want to be changed, I simply added a string value to the Tag property and have a method search for all controls of this type with the Tag property set to a specific string.
I initially thought I might be able to create a generic method that would change the text for all other controls and assign it to the TextChanged event of each control but I soon found out that they cancel each other out once I assign the value of one control to another (because in essence, once I change the value of one control, it then calls the same method and tries to change the rest).
Sorry if it's confusing, but here's some code as to what I'm trying to do...for now, let's say I have just 2 controls...lookupWeight and lookupBicycleWeight. On the TextChanged event for each, I have this:
private void OnLookupWeight_TextChanged(object sender, EventArgs e)
{
OnLookupWeight_TextChanged<LookUpEdit>(sender, e);
}
which calls this:
private void OnLookupWeight_TextChanged<T>(object sender, EventArgs e)
{
var controls = GetAll(tabPageSpecifications, typeof(T));
foreach (var control in controls)
{
if (control.Tag != null)
if (control.Tag.ToString() == "Weight")
if(control.Name != (sender as LookUpEdit).Name)
(control as LookUpEdit).EditValue = (sender as LookUpEdit).Text;
}
}
GetAll is a simple method that returns all controls for a given Control, including sub-controls:
/// <summary>
/// method to get all child & sub-child controls within a control by type
/// </summary>
/// <param name="control">the control we're searching in (use this for the form)</param>
/// <param name="type">The control type we're looking for (i.e; TextBox)</param>
/// <returns></returns>
public IEnumerable<Control> GetAll(Control control, Type type = null)
{
var controls = control.Controls.Cast<Control>();
//check the all value, if true then get all the controls
//otherwise get the controls of the specified type
if (type == null)
return controls.SelectMany(ctrl => GetAll(ctrl, type)).Concat(controls);
else
return controls.SelectMany(ctrl => GetAll(ctrl, type)).Concat(controls).Where(c => c.GetType() == type);
}
I know my OnLookupWeight_TextChanged method isn't entirely generic because I cast to the type LookupEdit but I am just trying to get this to work at this point before going back and changing things.
As you can see, the line if(control.Name != (sender as LookUpEdit).Name) is where the OnLookupWeight_TextChanged gets fired again and basically cancels itself out.
Any help or diretion as to how to accomplish this would be great.
Just change the ones that don't already have the same Text value:
foreach (var control in controls)
{
if (control.Tag != null)
if (control.Tag.ToString() == "Weight")
if((control as LookUpEdit).EditValue != (sender as LookUpEdit).Text)
(control as LookUpEdit).EditValue = (sender as LookUpEdit).Text;
}
It sounds like the code in OnLookupWeight_TextChanged shouldn't be run when the text of the control is changed from within that routine. You can use an instance variable to disable running it except when the change comes from outside. For example:
private Boolean InProgress;
private void OnLookupWeight_TextChanged<T>(object sender, EventArgs e)
{
if (!InProgress)
{
InProgress=true;
var controls = GetAll(tabPageSpecifications, typeof(T));
foreach (var control in controls)
{
if (control.Tag != null)
if (control.Tag.ToString() == "Weight")
if(control.Name != (sender as LookUpEdit).Name)
(control as LookUpEdit).EditValue = (sender as LookUpEdit).Text;
}
InProgress = false;
}
}
Why don't you use the same bindingsource for all the 10 controls?
When you change the selected value in one of them all would change.
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?
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);
}
Here is a method that doesn't rely on directly using private methods or reflection. It does still use undocumented interfaces though.
In .NET 4.0 the PropertyGrid.Controls collection contains 4 controls. PropertyGrid.Controls.item(2) is an undocumented PropertyGridView (same type as in answer that uses reflection). The property PropertyGridView.LabelRatio adjusts the relative widths of the columns. The range of LabelRatio looks like it is 1.1 to 9. Smaller values make the left column wider.
I know that setting LabelRatio before you initially display the control works. However I'm not sure what all you need to do to make it take effect once the control is already displayed. You can google MoveSplitterTo to find .NET source code and look at the source for PropertyGridView to get more details. The calculations and operations involving it seem somewhat complicated and I didn't analyze them in detail.
LabelRatio is initially set to 2 (ie splits the available PropertyGrid width in half). Set it to 3 for thirds, 4 for quarter.
Code requires Imports System.Reflection
Public Sub MoveVerticalSplitter(grid As PropertyGrid, Fraction As Integer)
Try
Dim info = grid.[GetType]().GetProperty("Controls")
Dim collection = DirectCast(info.GetValue(grid, Nothing), Control.ControlCollection)
For Each control As Object In collection
Dim type = control.[GetType]()
If "PropertyGridView" = type.Name Then
control.LabelRatio = Fraction
grid.HelpVisible = True
Exit For
End If
Next
Catch ex As Exception
Trace.WriteLine(ex)
End Try
End Sub
To change size of Description Pane at bottom of PropertyGrid as lines of text
Public Sub ResizeDescriptionArea(grid As PropertyGrid, lines As Integer)
Try
Dim info = grid.[GetType]().GetProperty("Controls")
Dim collection = DirectCast(info.GetValue(grid, Nothing), Control.ControlCollection)
For Each control As Object In collection
Dim type = control.[GetType]()
If "DocComment" = type.Name Then
Const Flags As BindingFlags = BindingFlags.Instance Or BindingFlags.NonPublic
Dim field = type.BaseType.GetField("userSized", Flags)
field.SetValue(control, True)
info = type.GetProperty("Lines")
info.SetValue(control, lines, Nothing)
grid.HelpVisible = True
Exit For
End If
Next
Catch ex As Exception
Trace.WriteLine(ex)
End Try
End Sub