Dmitry,
Now I see that for me the most appropriate would be to use a UserControl. Let me explain. In my VFP app I almost never drop data entry controls (textbox, label, etc) on forms. Instead data entry controls are placed on containers. Then, in the INIT of the form, the container is dynamically "placed" (don't know the right word) on the form.Yes, it sounds like a UserControl is just what you want to use.
This allows me to make customer changes for some customers as I can at run time (based on a certain setting) replaced a standard container with this customer specific (custom) container.
>
>I don't know if the above type approach is doable in WinForms. That is, can I dynamically instantiate/assign a UserControl to a form?Yep! You can do that using Reflection. You'd instantiate the UserControl dynamically with Reflection and then simply add it to the Form's Controls collection as you would for any control. I'm sure I've posted my Reflection class code here before, but since I'm in the middle of typing my response to you, I'm not going to go searching for it, I'll just re-post it here:
We do this constantly using Reflection. I've recently added a Reflection class to our "framework" because when we first designed our "framework" back in 2002, there were calls to Reflection stuff all over the place ... with all the error-checking constantly repeated everywhere, I figured it was better to have one class handle it all. So, I recently refactored our framework to use the new class. Below is a simplified version of my Reflection class (other things could be added to it, for example allowing parameters to be passed).
It's easy to use too. Here's one way to use it:
MyReflectionClass oReflection = new MyReflectionClass(assembly, classname);
string message = "";
object o = oReflection.InstantiateClass(ref message);
if (message != "")
MessageBox.Show(message);
else
{
}
And here's the simplified class:
public class MyReflectionClass
{
#region Declarations
private string m_AssemblyName;
private string m_ClassName;
#endregion
#region Constructors
public MyReflectionClass()
{
}
public MyReflectionClass(string assemblyName, string className)
{
this.AssemblyName = assemblyName;
this.ClassName = className;
}
#endregion
#region Methods
public Assembly LoadAssembly(ref string Message)
{
Assembly oAssembly = null;
try
{
oAssembly = Assembly.LoadFrom(this.m_AssemblyName + ".DLL");
}
catch (System.IO.FileNotFoundException)
{
Message = this.m_AssemblyName + " could not be found at the specified URL!" + (char)13 + (char)13 +
"Check that you have correctly entered the component URL and that your network or Internet " +
"connection is functioning correctly.";
return oAssembly;
}
catch (System.BadImageFormatException)
{
Message = this.m_AssemblyName + " is invalid or damaged!" + (char)13 + (char)13 +
"Contact your system administrator.";
return oAssembly;
}
catch (System.Exception ex)
{
Message = ex.Message;
return oAssembly;
}
return oAssembly;
}
public object InstantiateClass(ref string Message)
{
Assembly oAssembly = null;
return this.InstantiateClass(ref oAssembly, ref Message);
}
public object InstantiateClass(ref Assembly oAssembly, ref string Message)
{
object oClass = null;
if (oAssembly == null || oAssembly.FullName.Contains(this.m_AssemblyName) == false)
oAssembly = this.LoadAssembly(ref Message);
try
{
if (oAssembly != null)
oClass = oAssembly.CreateInstance(this.m_ClassName);
}
catch (Exception ex)
{
Message = ex.Message;
return oClass;
}
return oClass;
}
#endregion
#region Properties
public string AssemblyName
{
get { return this.m_AssemblyName; }
set
{
this.m_AssemblyName = value.Trim();
if (this.m_AssemblyName.ToUpper().EndsWith(".DLL", true, null))
this.m_AssemblyName = this.m_AssemblyName.Remove(this.m_AssemblyName.Length - 4);
}
}
public string ClassName
{
get { return this.m_ClassName; }
set
{
this.m_ClassName = value.Trim();
if (this.m_ClassName.Contains(this.m_AssemblyName) == false)
this.m_ClassName = this.m_AssemblyName + "." + this.m_ClassName;
}
}
#endregion
}
~~Bonnie
> Bonnie,
>
>Thank you for the explanation. Now I see that for me the most appropriate would be to use a UserControl. Let me explain. In my VFP app I almost never drop data entry controls (textbox, label, etc) on forms. Instead data entry controls are placed on containers. Then, in the INIT of the form, the container is dynamically "placed" (don't know the right word) on the form. This allows me to make customer changes for some customers as I can at run time (based on a certain setting) replaced a standard container with this customer specific (custom) container.
>
>I don't know if the above type approach is doable in WinForms. That is, can I dynamically instantiate/assign a UserControl to a form?
>
>>Dmitry,
>>
>>As Cetin says, you can use a Panel. As Kevin says, you can use a UserControl. In addition to those, it sounded to me like you also might be interested in using a GroupBox. All three of these controls have similarities, in that they're "containers", and you can visually drop stuff on them, but they are typically used for different purposes.
>>
>>UserControls are typically used as a "standalone" set of controls (IOW, you'd design a UserControl visually by dropping on TextBoxes, etc. and save it as a single class file, MyCustomerControl.cs for example).
>>
>>Panels are typically used for docking, along with Splitters, and are dropped on a Form or UserControl.
>>
>>GroupBoxes are typically used, as the name suggests, to visually group a set of controls together(TextBoxes,etc), and are dropped on a Form or UserControl.
>>
>>~~Bonnie