I'm creating a custom control that I want to be available from Visual Studio's toolbox. The class looks like:
[ToolboxData("<{0}:CustomPanel runat=server></{0}:CustomPanel>")]
public class CustomPanel : Panel
{
}
So far, so good. The control is inheriting from a Panel and once added to the toolbox can be easily dragged and dropped on the aspx page. What I want to do now is add new controls to this panel such as labels and some basic HTML tags. I tried the following without success:
[ToolboxData("<{0}:CustomPanel runat=server></{0}:CustomPanel>")]
public class CustomPanel : Panel
{
protected override void OnInit(EventArgs e)
{
Label name = new Label();
name.Text = "Hello jdecuyer!";
this.Controls.Add(name);
base.OnInit(e);
}
}
Any ideas?
To make this considerably easier. I would suggest:
1.) Create a UserControl then from the designer
2.) Add your custom panel class to that usercontrol
3.) Add your labels/links however you see fit.
4.) Add that UserControl to your Page
Ramhound is correct though, it seems you are not giving the label a location, though it should be slated to the top left automatically. And you are adding it to this as opposed to your panel.
Sorry I don't have much exp with asp. Hope this was somewhat helpful.
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.
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.
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 want to create my own component which consists two other panels. One of them has fixed contents (such as control buttons, etc.) and the other is standard panel, where I can add other components in designer (VS2008).
I know that I have to create UserControl, where I can place my two panels. Then I want to insert my component into the form. But I don't know how to create behavior where I can add other components (such as buttons, labels, etc.) only into second panel in my component.
Could anyone help me with creating this component?
Thank you.
Adam.
Here is an example (snippet of working code):
[Designer(typeof(NavigationalUserControl.Designer))]
public partial class NavigationalUserControl : UserControl
{
class Designer : ControlDesigner
{
public override void Initialize(IComponent component)
{
base.Initialize(component);
var nc = component as NavigationalUserControl;
EnableDesignMode(nc.panel2, "ContainerPanel");
EnableDesignMode(nc.bottomPanel, "BottomPanel");
}
}
// rest of normal class
}
I have found the correct solution (I hope). I have added into my UserControl a property which returns the content panel with this specific Attribute:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Panel PanelContent
{
get { return this.panel2; }
}
Thanks for your help leppie