How do I disable visual styles for just one control, and not its children?
Add a new class to your project and paste the code shown below. Build. Drop the new control from the top of the toolbox onto your form. Visual styles of the child controls are preserved.
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class FixedTabControl : TabControl {
[DllImportAttribute("uxtheme.dll")]
private static extern int SetWindowTheme(IntPtr hWnd, string appname, string idlist);
protected override void OnHandleCreated(EventArgs e) {
SetWindowTheme(this.Handle, "", "");
base.OnHandleCreated(e);
}
}
Disabling visual styles in manifest while retaining Common Controls functionality
To disable visual styles for all controls, call SetThemeAppProperties(STAP_ALLOW_NONCLIENT)
or SetThemeAppProperties(0)
before you create your main window.
To disable visual styles per HWND you can call SetWindowTheme(hwndControl,L"",L"")
If you need to support systems without v6 common controls you can probably figure out which system metrics (or hardcoded values) are used in the toolbar control by playing with the system metric values and system DPI.
TabRenderer with no visual styles enabled?
You have to draw it by yourself, because there is not published API for this. Hopefully this is relatively easy to do it in non-visualstyles way.
You can draw pane border with ControlPaint.DrawBorder3D and use something like the following code for buttons:
int Top = bounds.Top;
int Bottom = bounds.Bottom - 1;
int Sign = 1;
if (tabStrip.EffectiveOrientation == TabOrientation.Bottom)
{
Top = bounds.Bottom - 1;
Bottom = bounds.Top;
Sign = -1;
}
using (Pen OuterLightBorderPen = new Pen(SystemColors.ControlLightLight))
{
e.Graphics.DrawLine(OuterLightBorderPen, bounds.Left, Bottom, bounds.Left, Top + 2 * Sign);
e.Graphics.DrawLine(OuterLightBorderPen, bounds.Left, Top + 2 * Sign, bounds.Left + 2, Top);
e.Graphics.DrawLine(OuterLightBorderPen, bounds.Left + 2, Top, bounds.Right - 3, Top);
}
using (Pen InnerLightBorderPen = new Pen(SystemColors.ControlLight))
{
e.Graphics.DrawLine(InnerLightBorderPen, bounds.Left + 1, Bottom, bounds.Left + 1, Top + 2 * Sign);
e.Graphics.DrawLine(InnerLightBorderPen, bounds.Left + 2, Top + 1 * Sign, bounds.Right - 3, Top + 1 * Sign);
}
using (Pen OuterDarkBorderPen = new Pen(SystemColors.ControlDarkDark))
{
e.Graphics.DrawLine(OuterDarkBorderPen, bounds.Right - 2, Top + 1 * Sign, bounds.Right - 1, Top + 2 * Sign);
e.Graphics.DrawLine(OuterDarkBorderPen, bounds.Right - 1, Top + 2 * Sign, bounds.Right - 1, Bottom);
}
using (Pen InnerDarkBorderPen = new Pen(SystemColors.ControlDark))
e.Graphics.DrawLine(InnerDarkBorderPen, bounds.Right - 2, Top + 2 * Sign, bounds.Right - 2, Bottom);
Disable all controls within Groupbox
Why not just disable the GroupBox itself?
GB_Product_Entry.Enabled = false;
If you really must loop through them then separate the if
conditions:
foreach (Control cont in GB_Product_Entry.Controls)
{
if (cont is TextBox)
{
((TextBox)cont).ReadOnly = true;
((TextBox)cont).BackColor = SystemColors.Control;
}
else if (cont is ComboBox)
{
((ComboBox)cont).Enabled = false;
((ComboBox)cont).BackColor = SystemColors.Control;
}
else if (cont is CheckBox)
{
((CheckBox)cont).Enabled = false;
//((CheckBox)cont).BackColor = SystemColors.Control;
}
// Any other conditions here...
}
The issue is currently caused because inside the if
statement you cast cont
to TextBox
and them moments later cast it to ComboBox
. Well it can only be on or the other so the cast always fails at some point.
With the statements separated you know the type as it's filtered by the if
.
Set style for certain controls within window from contained usercontrol
I got it working in a not-so-elegant way, iterating over all controls and setting the property myself. While doing so I save the infomartion about which controls I changed to be able to reset the UI to the original state. I'm not really happy with that, but it seems to work. I would have prefered setting and un-setting some style, but I did not find a way to do so.
Here's what I ended up using, but feel free to post something better. First the disabling part:
visited = set()
def disableControls(control):
visited.add(control)
for childNumber in xrange(VisualTreeHelper.GetChildrenCount(control)):
child = VisualTreeHelper.GetChild(control, childNumber)
# save the old state
if type(child) in [Button, ComboBox, CheckBox] and child.IsEnabled:
child.IsEnabled = False
self.disabledControls.add(child)
elif type(child) == TextBox and not child.IsReadOnly:
child.IsReadOnly = True
self.disabledControls.add(child)
elif child not in visited:
disableControls(child)
disableControls(self.windowOwner)
And here's the part to "reset" the UI to it's original state:
while self.disabledControls:
child = self.disabledControls.pop()
if type(child) in [Button, ComboBox, CheckBox]:
child.IsEnabled = True
elif type(child) == TextBox:
child.IsReadOnly = False
the visited
-set is just a local variable to avoid visiting controls more than once, which strangely happens e.g. for some grids. The disabledControls
-set holds all controls that where not disabled and thus have been disabled by the code and have to be reset when the UI should reset itself to the original state.
Disable buttons, depending on where Form is opened from
You could add a property to the Form2 class like this:
public bool HideSomeControls
{
get;
set;
}
Then, right before you show the Form2 in Form1.cs, set that property:
form2instance.HideSomeControls = true;
form2instance.Show(); // or ShowDialog, depending...
Then, add a Load event handler to Form2 like this:
private void Form2_Load(object sender, EventArgs e)
{
if (HideSomeControls)
{
someControl.Visible = false;
someOtherControl.Visible = false;
}
}
Note that, if MainMenu
and Form1
share a single instance of Form2
, you'll have to set HideSomeControls
to false
again in MainMenu
before you show the Form2
instance.
Windows Forms:RightToLeft propety
if you set the "RightToLeft" property to Yes and "RightToLeftLayout" property to true, then the tab should move to the right side. surely it will work. please check your code or post your code.
or
you can do this through code, for example
Point p = new Point();
p.X = tabControl1.Location.X + 5;
p.Y = tabControl1.Location.Y + 5;
tabControl1.Location = p;
Related Topics
Object' Does Not Contain a Definition for 'X'
Why Is Modulus Operator Not Working for Double in C#
Why Aren't Generic Type Constraints Inheritable/Hierarchically Enforced
Linq to Xml - Update/Alter the Nodes of an Xml Document
ASP.NET C# Static Variables Are Global
Get Powershell Command's Output When Invoked Through Code
Convert Datetime to a Specified Format
Print HTML Document from Windows Service Without Print Dialog
Entity Framework Db-First, Implement Inheritance
C# Httpwebrequest the Underlying Connection Was Closed: an Unexpected Error Occurred on a Send
How to Ignore Get-Only Properties in JSON.Net Without Using JSONignore Attributes
How to Change Pixel Color of an Image in C#.Net
Authentication with Old Password No Longer Supported, Use 4.1 Style Passwords