[EDIT] To be clear, I know how to get a list of forms via reflection. I'm more concerned with the design time property grid.
I have a user control with a public property of the type Form.
I want to be able to select a form at design time from a dropdown.
I want to populate the form dropdown list from a set namespace: UI.Foo.Forms
This would work like if you have a public property of Control. At design time, the property will automatically populate a dropdown with all the controls on the form, for you to select from. I just want to populate it with all the forms in a namespace.
How do I go about doing this? I hope I'm being clear enough so there is no confusion. I'm looking for some code examples if at all possible. I'm trying to avoid having to spend too much time on this when I have other deadlines to meet.
Thanks for your help in advance.
Design-Time: It is the easiest method to set the DropDownStyle property of the ComboBox control using the following steps: Step 2: Drag the ComboBox control from the ToolBox and drop it on the windows form. You are allowed to place a ComboBox control anywhere on the windows form according to your need.
For example, public properties of a City data object can be constructed as design-time data. To use the class in XAML, you must import the namespace in the root node. The benefit here is that you can bind your controls to a design-time static version of your model. x:Array is not supported in UWP. Therefore we can use <d:ListView.Items> instead.
A design-time version of your namespace. This can be achieved by simply appending /design at the end. After you have taken all these steps, you can use your myDesignTimeControls prefix to create your design-time controls.
ListViews are a popular way to display data in your Desktop app. However, they're difficult to visualize without any data. You can use this feature to create an inline design-time data ItemSource or Items. The XAML Designer displays what is in that array in your ListView at design time.
You can easily get the classes via Reflection:
var formNames = this.GetType().Assembly.GetTypes().Where(x => x.Namespace == "UI.Foo.Forms").Select(x => x.Name);
Assuming you're calling this from code in the same assembly as your forms, you'll get the names of all the types that are in the "UI.Foo.Forms" namespace. You can then present this in the dropdown and, eventually, instantiate whichever is selected by the user via reflection once more:
Activator.CreateInstance(this.GetType("UI.Form.Forms.FormClassName"));
[Edit] Adding code for the design time stuff:
On your control you can create a Form property as such:
[Browsable(true)]
[Editor(typeof(TestDesignProperty), typeof(UITypeEditor))]
[DefaultValue(null)]
public Type FormType { get; set; }
Which references the Editor type that must be defined. The code is pretty self-explanatory, with a minimal amount of tweaking, you'll likely be able to get it to produce exactly what you want.
public class TestDesignProperty : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
var edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
ListBox lb = new ListBox();
foreach(var type in this.GetType().Assembly.GetTypes())
{
lb.Items.Add(type);
}
if (value != null)
{
lb.SelectedItem = value;
}
edSvc.DropDownControl(lb);
value = (Type)lb.SelectedItem;
return value;
}
}
The dropdown does not close when item gets selected by clicking it, so this could be useful:
assign the click event handler for the listbox and add the event handler function
public class TestDesignProperty : UITypeEditor
{
// ...
IWindowsFormsEditorService editorService;
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
// ...
editorService = edSvc ; // so can be referenced in the click event handler
ListBox lb = new ListBox();
lb.Click += new EventHandler(lb_Click);
// ...
}
void lb_Click(object sender, EventArgs e)
{
editorService.CloseDropDown();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With