I'm using TabControl and I have DrawFixed. I just want only draw the tabs not the panel under it.
How can I remove it?
Also I'd like to ask, can I change tabs size? I've long text which I'd like see all if it's selected but I'd like see it cropped if it's not active.
I've following in draw event, but it always draws the tab in the same size.
if (e.State == DrawItemState.Selected)
{
e.Graphics.FillRectangle(Brushes.White, e.Bounds.Left, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height);
}
else
{
e.Graphics.FillRectangle(Brushes.LightGray, e.Bounds.Left, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height);
text = text.Length > 10 ? text.Substring(0, 10) + "..." : text;
}
e.Graphics.DrawString(text, e.Font, Brushes.Black, e.Bounds.Left + 17, e.Bounds.Top + 3);
Thanks in advance.
Chronologically in your question, you have asked how to get rid of that bar at the top. If you insisted on using 'faux' tab pages where the tabs merely control content of the fixed set of controls, then shrinking the height of the tab control to a point where that isn't visible is probably an acceptable solution. I just tried it and with some tweaking it looks mostly what I think you are after. For the record I'd recommend actually using the tab pages as intended, that is as hosts to controls, even if you make a custom control that brings together all the controls you want visible. This will fit the tab paradigm much better.
For the second point you'd like to resize the tabs. Impossible. The framework gives two options for DrawStyle, Normal and OwnerDrawFixed. Normal allows Windows to set the tab size based on the text and font, OwnerDrawFixed means the tab size is completely fixed. There is no more control over this. OwnerDrawFixed however gives you access to the OnDrawItem event which is what you are wanting to use for painting the tabs themselves.
It now seems you've bitten the bullet and set UserPaint to True which means you are now doing all of the drawing. I recommend at this point to set DrawStyle back to Normal, then you can kludge some behind-the-scenes text to have Windows control the tab widths automatically. I will warn this won't be very robust since everyone has different font settings and a few pixels off and nothing will draw right.
So here I'll point out TabControl.GetTabRect(index As Integer), the method you can use to get the bounding rectangle of a given tab. I use this in a loop over all the tab indices and then do all the drawing I need for the tab within the rectangle provided from each tab. This means I don't need to use OwnerDrawFixed to get the bounds to paint within.
However still if you want better control, you're 80% the way to just implementing exactly whatever control you want to see, starting from either Control or UserControl. A similar look could be achieved from overlapping buttons with some logic to paint and lay them out. Then you could get all the text appearance you want also. I considered the same myself but didn't because I am still hosting TabPages. Since you're free from that it would be even easier...
Just use page text default property it will auto fix tab size for you according to the size of text.. then paint your text by your self .. if you still want additional space for painting image or some thing else then use padding which is the property of tab control not the tab page. i hope it will help full for you.
Related
I have a Windows Forms application which contains a couple of labels, a button and a combobox all wrapper inside a Panel.
this.pnlSuboptions.Controls.Add(this.label1);
this.pnlSuboptions.Controls.Add(this.cboPtSize);
this.pnlSuboptions.Controls.Add(this.label2);
this.pnlSuboptions.Controls.Add(this.btnSelect);
I facing an issue with my labels when I try loading localized strings for my labels. The localized strings for some languages are larger than the English strings. In such cases, a part of the label gets hidden under the combo box or the button.
I want the label to increase in size towards the left instead of right. I've set my labels' AutoSize property to true and also played around with the Anchor property but nothing seems to work.
I found an SO link which contains a solution to this problem when the label text changes but I'm sure how I can apply this in my scenario where the label is read only once during the form load.
Any suggestions?
You could put them into a TableLayoutPanel with 2 columns and two rows. Each label goes in left side of each row and both combo box/buttons goes in the others cells (right side of each row).
Then you must dock both elements (Dock Fill) and set the columns to AutoSize. (As you can see in the image)
You also may want to dock the TablePanelLayout to your common panel.
As you can see in the image below, both TablePanelLayout have the same components. But in the secoend I just changed the label3's text.
Hope it helps. (Also sorry for my bad english, it isn't my native language. Please feel free to correct any wrong spelling, thanks!)
First suggestion from me would be:
set the AutoSize property to False
Make sure that the width is alot larger than it needs to be by resizing the label.
The label should now fit nicely regardless of what content it receive.
Second suggestion, you can use the GDI+ to determine the size of the text and then resize the label accordingly See http://msdn.microsoft.com/en-us/library/6xe5hazb(v=vs.110).aspx
Graphics gfx = this.label1.CreateGraphics(); // I think its called that, cant remember :)
Font stringFont = new Font("Arial", 16);
// Measure string.
SizeF stringSize = new SizeF();
stringSize = gfx.MeasureString(this.label1.Text, stringFont);
this.label1.Size = new Size((int)stringSize.Width, (int)stringSize.Height);
Oh yeah I almost forgot. Make sure that you're panel is not the cause of the clipping. I mean, check if the panel is large enough for the labels to fit :-)
Hope this helps!
Best regards,
Zerratar
So, doing what I'm attempting to do is trivial in WPF, but in WinForms it seems to be a bit problematic:
When using a TableLayoutPanel, you can simply set the Anchor properties to NONE to center the control within the cell of the TableLayoutPanel and then set Anchor.Right | Anchor.Left flags on the control to stretch it to the size of the cell. This behavior does not seem to work properly when using a standard WinForms Panel container. When setting the Anchor property on the child control (TextBox) within the Panel the control does not appear to stretch out, nor center itself within the container.
I've looked up some other answers regarding similar issues to this, but I feel like I'm missing something here. Most of them say just use the Anchor property, but that doesn't not appear to work. Does this need to be manually calculated on load (and each resize), or can the Anchor property actually assist me with this?
Keeping a Control centered works automatically only if you combine stretching it with Anchors.
If you want it centered without stretching it you'll have to do a little bit of math in the Resize event:
private void tableLayoutPanel1_Resize(object sender, EventArgs e)
{
yourControl.Left = (yourControl.Parent.ClientSize.Width - yourControl.Width) / 2;
}
For centering vertically the same rules apply.
With regard to the disappearing ErrorProvider: The ErrorProviders need a little space, on my machine 12 pixels will do. To provide that space for the rightmost cells in an TableLayoutPanel you can set its padding like this:
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(0, 0, 12, 0);
Note how this nicely adds the padding between the Cellborders, if you have any, and the outside.
It seems that MSDN has a page dedicated to this already. (although this mentioned a button, the idea remains the same)
I have a simple winforms app with a column of several buttons. What is the nicest way to enforce that they are equally spaced vertically?
Drag a rectangle around them in the designer so they all get selected. Use Ctrl + Left mouse click to adjust the selection if necessary. In the menu: Format + Vertical Space + Make Equal.
If you want to make the spacing dynamic (ie: it updates when the user changes the size of the window) the best approach would be to create a TableLayoutPanel with 5 rows (and probably just one column). Set its Dock property to Fill, and make sure each row has automatic size.
After that, you place your buttons on the panel, and it will do the positioning for you.
Set the top and bottom margins on each control to the same thing, and then drag them together using snaplines to line them all up.
Change the location parameters in the properties windows to be proportionally aligned.
So in winforms, every dropdown combobox has this little arrow thingy to the right that tells the user it's a dropdown, kinda like this:
Now how do I figure out how wide that is in pixels? Reason is, I'm using ControlDrawToBitmap, this doesn't draw the text properly for the combo boxes, and I can redraw the contents, I just whack some of the arrows (which are drawn properly).
First idea that comes to mind: Check to see if the combobox button width tracks with the scrollbar width. The scrollbar width can be modified in user preferences. Use GetSystemMetrics() API to get the width of the various scrollbar pieces. If you change your system scrollbar width and it does not affect the size of a normal combobox, then ignore this.
Second idea: use the edit control's formatting rect to find out what the edit control thinks is the usable display area (minus the combo box). See EM_GETRECT in MSDN.
However, it sounds like this is just a hack workaround for your real problem: If you could get the controls to draw correctly to bitmap, then you wouldn't need this hackery.
I calculated it to be 9 pixels wide in photoshop
I'm developing an app for Windows Mobile 5.0 and above, with C# and .NET Compact Framework 2.0 SP2.
I have a WinForm with two panels inside (upperPanel and bottomPanel). I want that upperPanel always fill 2/3 of form's height, and bottomPanel fills 1/3 of form's height. Both panels will fill completly form's width.
I've used this:
upperPanel.Dock = Fill;
bottomPanel.Dock = Bottom;
But upperPanel fills the form completly.
How can I do this? I want, more o less, the same gui on differents form factors and on landscape or protrait mode.
Thank you.
What you need to do is to put the bottom panel on first and set its Dock property to Bottom. Then set the panel's height to be 1/3 of the form's height. Finally, add a second panel and set its Dock property to Fill. The key here is that you want to add the control that will fill the remaining area to be added last. Alternatively, you can play around with the Bring to Front and Send to Back commands in Visual Studio to get the designer to cooperate.
You may also need to hook the OnSizeChanged event for the form and re-set the height of the bottom panel to account for layout changes. It's been a little while since I did compact framework programming, so I'm not sure.
Right click on the upperPanel and select Bring To Front. However, I don't think this will give you the result you want. When you resize, the bottom panel will remain the same height, while the upper panel will stretch to fill the form.
Using your docking settings, with this code might do the trick:
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
this.bottomPanel.Height = Convert.ToInt32((double)this.Height / 3.0);
}
Set both panels to "not anchored". That is: Remove Dock-Value and clear the Anchor property. Then, move the controls so they are sized the way you'd like them to be sized.
After that, upon resizing the form, they should resize relatively.
EDIT
Oops, just tried it and sure it doesn't work. I mixed this up with a solution that automatically keeps controls centered within the window...
Well, I'd guess you then have to create a handler for the form's Resize event and manually align the controls after the form has been resized.
Go to Tools, Other Windows, Document Outline. Find the two panels, and swap the order of them. The control that has DockStyle.Fill has to come first for it to be docked correctly. (or last.. never sure which one it is, but it is one of them :p)
This won't solve the always 1/3 and 2/3 issue though... cause the bottom panel will have a fixed height (unless I am mistaken). I think maybe the TableLayoutPanel supports this though...
Update: As noted in the comments, that panel doesn't exist in the compact framework. So, I suppose the easiest solution to this problem would then try to use the docking, but update the height of the bottom panel whenever the size of the form changes.
If you want this to work perfectly you'll need to add some code to the Resize event of the Form which then specifically works out the relative sizes and places the controls in the correct place after a resize.
If you're not worried about losing precision and the forms aren't going to move much you can avoid this by using some relatively smart anchoring. Essentially you're going to have to select a "grower" (the part of the form that gets bigger, the bigger the form gets). In this scenario I would probably anchor the top part to Top | Left | Right and the bottom part to Top | Left | Right | Bottom. This would mean that the lower part of the form will get bigger if the form is expanded. In most cases this is acceptable. If it isn't use the Resize event and some code.
The easiest way to do this is to nest panels. Just set up panels for top bottom and fill. Then use panels within those panels to do the same. The only issues I've had therein are datagrid resizing, which is always a pain anyway. in that case, you have to use some code to resize the datagrid control on the form resize event.
I would like to add a point to #jasonh answer.
For the panel that occupies 2/3 of the form, you will have to set the AutoScroll property of the panel to true.
This will enable the panel to display scroll when the control size exceed the visibility to the user and also ensure the visibility of the smaller panel which is 1/3 of the forms height.
You can get the required design by using nested panels along with few setting with Anchoring and Docking Properties.Follow the following steps:
1) Add the Form and put a Panel1 on it. Set its Dock Property as 'Fill' and ResizeMode as 'Grow&Shrink'.
2) Add Second panel2 and set its Dock Property to 'Bottom', Set the Height and set the Anchor property to 'Top,Left'.
3)Add Third panel and set its Dock Property to 'None', Set the Height and set the Anchor property to 'Top,Bottom,Left,Right'.
Save and Compile. Now all the panels Would maintain their relative Positioning With resizing.