Losing styles when adding a User Control to a User Control - c#

In my project, I am trying to add a button collection user control to an input based user control. The button uc is going to be added to numerous other controls. The problem that I've encountered is that the button uc is losing whatever css styles that I've attach to it, once it is added to the parent uc. Initially, I had a panel on the parent that would add the button uc when the page was loaded, then I would add the button uc to the panel:
(panel.controls.add(uc)
This did not work, the styling of the buttons were lost. Next, I tried to set the positioning to the button uc and add it directly to the form:
static void SetLocation(Usercontrol uc) {uc.Attributes.add("style","left:425px;top:420px;"); }
public void SetPage() { button = (uc)LoadControl(button.ascx); SetLocation(buttonuc); this.Controls.Add(buttonuc); }
But, this did not work either, it did not even locate the control properly. My style sheet is already added to the parent uc, and the button uc to be added has its style on that sheet. I don't want to have to manually add the buttons to each uc parent. Thank you for any help. I sure I'm just missing something obvious, but I've yet to come upon a similar issue in a search. Thank you.

In general it is good practice to keep your styles separate from the markup. This makes maintenance easier and it also saves yourself from searching for the reason one of your elements appears a pixel away from where you are expecting (for example... Similar issues can be exasperating).
Do you have the same issue if you set the CssClass attribute for your button(s) and set the styles in a css file for the class?

Related

User control Anchor property issue

Context :
I created an User Control. For some reason, I want to use this control in different size. To keep the initial "Template" of my User Control when re-sizing, I use the property Anchor on my different element inside the control.
So when I create my control at design time, it is possible to me to hand re-size the control and keep the original "Template" of it.
When the control is created, it look like this :
And after re-size :
As you can see, the property Anchor work well.
The label and the picture stay in the middle.
The "?" stay to the left corner.
The problem :
The problem I have is, when the control is reloaded, created with a different size as the initial one, all the elements inside return to their initial position :
I don't know if this is the better way to do what I try to achieve. Keep in mind that I add and re-sizing the control's during the design time.
Thank you.
EDIT :
I think my problem is caused by the designer. Ex : I add my control in the designer, I re-size it, I run the solution. All is working good. But when I go to the code of the page, and then, return to the designer, the element inside the control returned to their initial position.
EDIT 2 :
Ok I have found a solution, I simply moved all the element of the User control inside a Panel. For some reason that I can't explain, it work perfectly. The control's stay at the same location.
The solution is ta add a Panel to the User Control and dock it to "Fill", then place the element inside of this panel. For some reason that I can't explain, the designer keep the location of the re-sized control's elements.
The anchoring, docking and auto-sizing of a UserControl seem to be terribly confusing. I found UserControl does not auto resize with the Form which suggests that you set the AutoSize property to False, which I did, and it still didn't correct my problem. But when I tried your solution, I also noticed there are two copies of the AutoSize property! I had set the AutoSize in the UserControl designer to False, but the Form designer where the UserControl instance was added also had an AutoSize on the instance, and that one had a different value (it was still True). When I set that to False also, then everything worked (with the panel in place). Then I removed the panel you suggested, and everything still worked. So I guess the trick is to make sure you check all the properties of the UserControl in the UserControl designer and in the form designer where the control is used. Then you shouldn't need a panel.
I've had similar problem in VS2015 project, and unfortunately - none of your answers helped. Clean and working solution was found here, in Jignesh Thakker answer.
For quicker navigation here it is how it was done in my project (c++/cli, not c#, but idea is the same):
System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
/* some code */
myUserControl = gcnew MyUserControl();
myUserControl->Dock = DockStyle::Fill;
tabPage1->Dock = DockStyle::Fill;
tabPage1->Controls->Add(myUserControl);
/* some code */
}
Set the Localizable property of the parent form at VS designer to false. This solves the problem at design time. (Save, close and reopen the form after switching the property)
If you need a localized application switch the Localizable property to true after finish up working at the layout and don't care about the wired representation in the VS designer. At run time it's shown correctly.
Tested in VS2013

Load User Controls dynamically based on other control events

I have a "cross section" of variables that I need to use to generate a set of user controls dynamically. In the center of the page I have a Telerik multitab/page. I have a custom tree menu and a custom menubar, based on the combination of menu input each of the tabs should load a user control relevant to that cross section of data.
For clarity, almost each tab, treeview, menubar combination needs a unique control.
My problem is that all the postback/loading happens well before the "OnMenuChanged" event triggers, so I'm one "set" of user controls behind. Even if I were to use session/viewstate they wouldn't get assigned until after I needed the value stored in them.
Currently what is happening is the default user controls are loaded in the "pageviewcreated" event, then in the onMenuItemChanged I go back and reload the user controls. It seems very inefficient and is complicating up the approach for selecting the right .ascx.
How do I manage this?
If I understand what you're trying to do could you not use a placeholder control and inject your needed usercontrol into that inside of the events you're managing? Try doing something like this inside of the "OnMenuSelected" event.
WebUserControl1 uc = (WebUserControl1) Page.LoadControl("WebUserControl1.ascx");
PlaceHolder1.Controls.Add(uc);

Custom GroupBox control with other controls inside

I didn't like any available solutions so I started to make my own wizard interface. I use a GroupBox for each step of the wizard but since every step (every GroupBox) must have the same structure and style, I decided to use custom controls.
Now I need a custom GroupBox which has these elements:
A FlowLayoutPanel so the developer can put desired controls in it using the designer. (For example two TextBox controls so the user can enter a username and a password.)
A Label in that FlowLayoutPanel to describe the step.
A Button to go back.
Another FlowLayoutPanel that user can put custom buttons in.
Here is a preview:
Problem #1
When I create a new UserControl and make it inherit the GroupBox, I can't get a GroupBox that I can put and position stuff in it. All I see in the designer is this message:
Problem #2
Since I couldn't make it inherit GroupBox like I wanted it to, I tried doing it by putting a GroupBox in the custom UserControl. (I don't want this. I just did this so I could provide some screenshots.) After I did that, I had to EnableDesignMode on the FlowLayoutPanels so the developer could add controls in them by using the designer. The problem is that they also became movable and resizable (I don't want this. They are anchored properly and they should not be moved nor resized.) and when you try to move them you get "Object reference not set to an instance of an object." which is making it uglier:
Problem #3
I want elements in the main FlowLayoutPanel to be centered. To do this, I had to put a control (the description label) and resize it to the width of the FlowLayoutPanel so the controls after it would be centered. (Messy workaround if you ask me. Doing this with TableLayoutPanel looked easier but their cells can only hold one element. You can add a Panel to make the cell hold more elements but then you lose centering.) The problem is that I have to set Anchor to None for every control I add. Can I hook something (like OnDesignerControlAdded???) to automatically set added control's Anchor to None?
All of your answers will help me build the open source project Magician on GitHub and many other open source projects powered by it. Thanks in advance for all of your efforts.
Quick answer for problem #1:
Design your groupbox (GroupBox1) on a Form or a UserControl (it doesn't matter).
Go to InitializeComponent() in the designer.cs file and copy all code related to the groupbox and its child controls.
Add a new Custom Control called CustomGroupBox to the project.
Change it to inherit from GroupBox:
public partial class CustomGroupBox : GroupBox
Paste all the copied code into the constructor of CustomGroupBox (or into a new method, which you call from the constructor after InitializeComponent(), if you want to be neat).
Remove all occurrences of this. from the pasted code. Replace all occurences of GroupBox1 with this.
For any child controls you want the developer to have access to, add a public property for that control.
E.g.
public FlowLayoutPanel FLP
{
get { return flowLayoutPanel1; }
}
And of course add your CustomDesigner
public class CustomGroupBoxDesigner : ControlDesigner
{
public override void Initialize(IComponent component)
{
base.Initialize(component);
var c = component as CustomGroupBox;
EnableDesignMode(c.FLP, "FLP");
}
}
And apply the attribute
[Designer(typeof(CustomGroupBoxDesigner))]
public partial class CustomGroupBox : GroupBox

Adding the same Panel to multiple TabPages

In my previous question I could add a design time panel to a tab page at run time and my code looks like this and it works Ok.
tabControl1.SuspendLayout();
tabControl1.TabPages[0].Controls.Add(panel1);
tabControl1.ResumeLayout();
but now I need to do something like this:
tabControl1.SuspendLayout();
tabControl1.TabPages[0].Controls.Add(panel1);
tabControl1.TabPages[1].Controls.Add(panel1);
tabControl1.TabPages[2].Controls.Add(panel1);
tabControl1.ResumeLayout();
which just at run-time I can know how many of these Tabpages I will need. but now for testing I am assuming I will have three tabPages
the Problem is that the panel only gets added to the Last tabPage,
How can I fix this? I want it get added to all of the tab pages
Thanks.
You can't. A control can have only one parent at a time. Luckily, only one tab page is visible at a time, so I guess you could move the panel between the pages as they are displayed? On the other hand, if the panel is to be located in the same place for all pages, perhaps it should not be placed inside the tab control, but rather on top of it?

Why are controls within custom panel (C# winforms) disappearing in designer?

I have been able to create a custom C# winforms control that is basically a panel with a fixed banner (header/footer). I want to base other user controls on this "banner panel". I've gotten past the problem with the designer here. I can successfully add controls to the inner content panel. Everything looks fine while designing. However, when I recompile, the controls I added to the content panel disappear. They are still there (in code) but aren't displayed in the designer. Is there any thing that I need to do to set the drawing order of the controls?
Your controls are still nested correctly within the panel control, they have just lost their z-order. If you choose the controls from the property panel and right click on the control border that appears within the parent panel and select "Bring To Front" from the layout toolbar, your nested controls will re-appear. I don't know why it does this, but a workaround is to bring all child controls to the front during control initialization in the code.
There is really nothing to go on here without src. What I would do is to comment everything out including in the InitializeComponent function but a widget in the middle panel and run. Do whatever it takes to get that one widget to show. Inherit from UserControl instead of the banner panel.
Then comment in each piece until the widget no longer comes up. That is what is causing your problems. Once it all comes up properly, then you make sure the designer portion of the src works. It is going to potentially be a long process.

Categories