I have a form with a splitcontainer. One of the panels in the splitcontainer then loads a user control. This user control contains a combobox with the following properties changed from default:
DrowdownStyle=DrowDownList
FlatSyle=flat
Anchor=top,left,right
When the form and user control load, the combobox looks as expected:
However, if I resize the splitcontrol, it starts looking weird. If I increase the size of the panel that holds the control, this happens:
If i decrease the size of the splitter, it looks less weird, but still not how it is supposed to:
In either case, the combobox starts looking normal once I mouse over it.
Here is my code:
Main Form:
//Main form. Has a split container created from the toolbox
public partial class SampleForm:Form
{
public SampleForm()
{
InitializeComponent();
SampleControl cntrl = new SampleControl();
splitContainer1.Panel1.Controls.Add(cntrl);
splitContainer1.BorderStyle = BorderStyle.FixedSingle;
cntrl.Dock = DockStyle.Fill;
}
}
User Control:
//User control. Has a combobox created from toolbox. Options as described above
public partial class SampleControl : UserControl
{
public SampleControl()
{
InitializeComponent();
}
}
How can I fix this problem?
May be try to set dock to None . Also try to fix the margin for control
I know this is old, but was having the same problem and just in case someone finds themselves in the same predicament, answer below. Basically, create a new Class:
Imports System.Windows.Forms
Public Class MyComboBox
Inherits ComboBox
Protected Overrides Sub OnResize(e As EventArgs)
Me.Refresh()
End Sub
End Class
You can either drag this from your toolbox or add it in code. It will then auto redraw itself on resize of any parent controls.
Winforms is a bit like a sibling - flawed and deeply annoying sometimes - but you just gotta love it.
Related
I want to extend a GroupBox by adding a button on the caption. If I do this
public partial class MyInheritedGroupBox : GroupBox
{
public MyInheritedGroupBox()
{
InitializeComponent();
}
}
Works at runtime, but the control itself can't be edited anymore in the designer. Double clicking on the control now shows this
Is there some magic attributes so it shows up in the designer?
I'm trying to avoid inheriting from UserControl because it then introduces other complexities like this
Not sure what you want, there are 2 things that could be possible.
1, After dropping your control on a form you are not able to edit it using the designer and the object inspector. If that is the case you can solve it like this :
[Designer(typeof(ControlDesigner))] //without this you cannot change properties in the designer
public partial class MyInheritedGroupBox : GroupBox
{
public MyInheritedGroupBox()
{
InitializeComponent();
}
}
2, You want to build your control visually by double clicking on the class in the solution explorer.
If that is the case than you are out of luck.
You will need to create a UserControl for that.
This might be kind of beginner question but I searched and didn't find any clear answer!
The main question is: How to inherit properties of a control (specially FlatStyle) from a base form which doesn't have that control in C#?
Details: I have Form1 inherited from baseForm. baseForm has a Panel and a Label control but no Button. In Form1 I added a button named Button1. How can I change the style of that Button through the baseFrom?
I don't want to create a custom control or redesign the button using rectangles or similar ways, but only change that property for all buttons in my application.
UPDATE: I want all of the buttons to be affected, whether they already exist or just added. Not matter in which -if any- container they are.
In baseForm, you could hook the ControlAdded event on the Panel where the Button is to be added, and style appropiately via code. This will work for every form inherited from baseForm.
For example (in baseForm)
public partial class BaseForm : Form
{
public BaseForm()
{
InitializeComponent();
// "myPanel" is the panel where the button will be added in inherited forms
myPanel.ControlAdded += myPanel_ControlAdded;
}
private void myPanel_ControlAdded(object sender, ControlEventArgs e)
{
var button = e.Control as Button;
if (button != null)
{
button.FlatStyle = FlatStyle.Flat;
button.ForeColor = Color.Red;
}
}
}
Just made a really quick test... it works even in design mode:
As an alternative, if you are going to use heavily styled buttons everywhere in your application, you may consider creating a custom control inheriting from Button, and assign the properties there, like:
public class FlatButton : System.Windows.Forms.Button
{
public FlatButton()
{
FlatStyle = FlatStyle.Flat;
}
}
After building, you will find it in the Toolbox (under "[Your Project's] components" tab), or you can cram it on your own control library (in a different solution) and add it permanently to the Toolbox in Visual Studio.
You would need to make use of Reflection
You can use a LINQ query to do this. This will query everything on the form that is type Button
var c = from controls in this.Controls.OfType<Button>()
select controls;
foreach(var control in c)
control.FlatStyle = FlatStyle.Flat;
hi all and sorry for the confusing title... can't find the right words yet.
just out of curiosity, I am playing with c# user control, I created a control that is built from a panel, a textbox that is being used as a filter, and some labels / buttons/ etc... that are being filtered.
when ever you change the text of the textbox, all the controls on the panel are visible / invisible depending if their Text property contains the Text of the textbox. very simple.
but I want this user control to be such that the user that uses it can drop more labels or controls to it and they will behave the same, I can't figure out how to do that..
when I am editing the control (adding controls to it), it works as expected and the new controls behave as the old ones without code modifications, but only when I am editing the user control and not when using it.
when I am dragging the user control to a form, I can not add controls to it... when I try to add a label to the control - it is just added to the form and not to the control and therefore the text box is not influencing the added label. what should I do if I want to be able to add the control to a form and then add some controls to the control?
I will be happy for some pointers.
here is the relevant code:
private void textBox1_TextChanged(object sender, EventArgs e)
{
foreach (Control c in panel1.Controls)
{
if (c.Text.Contains(textBox1.Text))
{
c.Visible = true;
}
else
{
c.Visible = false;
}
}
}
edit - pictures added.
as you can see - i typed 1 in the filter text box and all the controls except button1 are now invisible - and of course the bad behaving label.
Thanks,
Jim.
This problem can be solved easily by following the guidelines in
https://support.microsoft.com/en-us/kb/813450 which decribes step by step How to make a UserControl object acts as a control container design-time by using Visual C#
In order to modify the user control as a design time control container
add the following code to the Declarations section:
using System.ComponentModel.Design;
Apply the System.ComponentModel.DesignerAttribute attribute to the control as follows:
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public class UserControl1 : System.Windows.Forms.UserControl
{
...
}
Then build the solution.
the control will appear as usual in the Toolbox and can be added to forms. Additional controls such as buttone , text boxes etc.. can be added to the control as required.
You describe one of the reasons why I almost never use UserControls. Anything that isn't done to the original UC must be done in code..
You can instead make it a class that is not a UserControl, ie make it a simple subclass of Panel (or FlowLayoutPanel as I do here merely for convenience, while dropping stuff on it during my tests).
class FilterPanel : FlowLayoutPanel
{
TextBox tb_filterBox { get; set; }
Label st_filterLabel { get; set; }
public FilterPanel()
{
st_filterLabel = new Label();
st_filterLabel.Text = "Filter:";
this.Controls.Add(st_filterLabel);
tb_filterBox = new TextBox();
this.Controls.Add(tb_filterBox);
// st_filterLabel.Location = new Point(10, 10); // not needed for a FLP
// tb_filterBox.Location = new Point(100, 10); // use it for a Panel!
tb_filterBox.TextChanged += tb_filterBox_TextChanged;
}
void tb_filterBox_TextChanged(object sender, EventArgs e)
{
foreach(Control ctl in this.Controls)
{
if (ctl != tb_filterBox && ctl != st_filterLabel)
ctl.Visible = ctl.Text.Contains(tb_filterBox.Text);
}
}
}
Now after placing it on a form (or whatever) you (or whoever) can drop Controls onto it in the designer and they'll be part of its Controls collection, just like you want it and will behave as expected..
Two notes on subclassing Controls:
If you break one during developement, the Form(s) using it will be broken, too, until you fix the problem. So take a little extra care!
For the Designer to display the Control it always needs to have one parameterless constructor, like the one above. Even if you prefer to have the ability to hand in parameters, one parameterless constructor must still be there or the designer will get into trouble!
I'm building a small tabbed c# Form and I'd like each tab page to have some common features, notably, an OK button and an error message and to have a space for the specific form fields.
Has anyone else done something similar and how did you approach it?
This is easy to do without extending either TabControl/TabPage.
Define one UserControl, and put the common elements on it you want on every TabPage.
On the Form: go ahead and design the TabPage specific controls you want for each TabPage : make sure they are not going to visually overlap with the common controls once the UserControl has been added.
In the Form Load Event of your main Form do something like this :
// form scoped variable to hold a referece to the current UserControl
private UserControl1 currentUserControl;
private void Form1_Load(object sender, EventArgs e)
{
foreach(TabPage theTabPage in tabControl1.TabPages)
{
currentUserControl = new UserControl1();
theTabPage.Margin = new Padding(0);
theTabPage.Padding = new Padding(0);
theTabPage.Controls.Add(currentUserControl);
currentUserControl.Location = new Point(0,0);
currentUserControl.Dock = DockStyle.Fill;
currentUserControl.SendToBack();
}
}
Even though the 'SendToBack isn't really required here it is "insurance" that your UserControl with the 'Okay button and TextBox for an error message are placed behind the individual controls you have assigned to each TabPage.
Several ideas:
Keep the common controls outside the tabpanel;
Extend the TabPage/TabControl
Create a base UserControl with the common buttons and make usercontrols that inherit from it. Then place one inherited usercontrol per TabPage.
In java swing I can insert panels into panels and so on, and not have to build a brand new window for every view of my applicaiton, or mess around removing and adding controls.
Theres a panel clas sin C# however I cant see any way of creating a 'panel form' or basically just a form in form designer thats a panel and its contents.
How do I do this then and work the way I did with java swing?
Usually i just dock different forms within eachother setting the IsMdiContainer Property to true on the parent window. Then i create subforms that i dock using the following function:
static class FormUtil
{
static public void showForm(Form sender, Control reciever)
{
sender.ControlBox = false;
sender.FormBorderStyle = FormBorderStyle.None;
sender.ShowInTaskbar = false;
sender.TopLevel = false;
sender.Visible = true;
sender.Dock = DockStyle.Fill;
reciever.Controls.Clear(); //clear panel first
reciever.Controls.Add(sender);
}
}
then whenever i need to dock a form inside a panel on the parents form i just do:
FormUtil.showForm(new SomeForm(), this.splitContainer1.Panel1);
This allows me to delegate some of the form creation to different designers. Works like a charm for me, love to hear if theres a better way of doing it.
Actually, you can use the panel control and set it's Dock property to Fill. That way, your panel will be the entire canvas of the form. Then, you can add child panels as needed either through code behind or through forms designer.
There's the concept of user controls which basicly provides you with a panel like designer surface , not to mention that you can create atomic forms (which can be reused) and register them as inheritable, that way you can provide inheritance too.