How to Disable Visual Styles for Just One Control, and Not Its Children

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



Leave a reply



Submit