Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting Dark mode #4

Closed
modz2014 opened this issue Dec 12, 2022 · 20 comments
Closed

Setting Dark mode #4

modz2014 opened this issue Dec 12, 2022 · 20 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@modz2014
Copy link

hey mate any chance you could tell me where to add dark mode for multiple forms and if the forms have groupbox in them ect i could only just get the title bar in dark mode

@Aldaviva
Copy link
Owner

Hello, I don't know much about making the client areas of Windows Forms windows use dark mode, sorry. I think older versions of Git Extensions 3.x did this nicely, although it was temporarily disabled in the latest 4.0. Most of the other solutions I've seen involve using MahApps or other UI frameworks with WPF.

@modz2014
Copy link
Author

can you make an example using Git extensions

@Aldaviva
Copy link
Owner

No, I don't know how the people working on the Git Extensions program accomplished this, I just know it's an open-source project which faced and solved the same sort of problem you're talking about. Their codebase may be a good starting point for figuring out techniques to make a dark UI in Windows Forms.

@modz2014
Copy link
Author

can we enable this at runtime when the uses clicks on the checkBox to enable and disable it

@Aldaviva
Copy link
Owner

Great idea. That will be possible.

First I have to make the "called too late" error check only run the first time for a given window. Otherwise it will throw an exception when the checkbox is clicked.

Once I develop and release that fix, you will be able to call DarkNet.Instance.SetWindowThemeForms(Form, Theme) in the checkbox event handler method.

@Aldaviva Aldaviva self-assigned this Dec 26, 2022
@Aldaviva Aldaviva added the enhancement New feature or request label Dec 26, 2022
Aldaviva added a commit that referenced this issue Dec 26, 2022
…indow is visible without throwing an InvalidOperationException
@modz2014
Copy link
Author

modz2014 commented Dec 27, 2022

ok that would be good can you release an example as well for checkbox please also is there a way to add it to multiple Forms though is the next question

@Aldaviva
Copy link
Owner

To change multiple forms themes all at once, you can do the following.

  1. When the program starts, call DarkNet.Instance.SetCurrentProcessTheme(theme) where theme is what you want all the forms to initially use at startup, such as a default value, persisted user preference, or Theme.Auto to use the Windows setting.
  2. When creating each form and before showing it, call DarkNet.Instance.SetWindowThemeForms(form, Theme.Auto). One way to make this less repetitive might be to put it in the constructor of a custom superclass of all your Form subclasses.
  3. When you want to change the theme of all Forms at once, then call DarkNet.Instance.SetCurrentProcessTheme(newTheme).

@modz2014
Copy link
Author

yer i am trying to use the checkBox call so ill wait for the updated example

@Aldaviva
Copy link
Owner

I was able to add this checkbox behavior to the darknet-demo-winforms project by making the following changes, along with the fix in 01d809b.

Form1.cs

  • Added a new CheckBox with the following properties
    • ThreeState = true
    • CheckState = Indeterminate
    • Details in Form1.Designer.cs InitializeComponent():
      show
        // 
        // darkModeCheckbox
        // 
        this.darkModeCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
        | System.Windows.Forms.AnchorStyles.Left) 
        | System.Windows.Forms.AnchorStyles.Right)));
        this.darkModeCheckbox.AutoSize = true;
        this.darkModeCheckbox.Checked = true;
        this.darkModeCheckbox.CheckState = System.Windows.Forms.CheckState.Indeterminate;
        this.darkModeCheckbox.Location = new System.Drawing.Point(704, 470);
        this.darkModeCheckbox.Name = "darkModeCheckbox";
        this.darkModeCheckbox.Size = new System.Drawing.Size(148, 29);
        this.darkModeCheckbox.TabIndex = 1;
        this.darkModeCheckbox.Text = "Dark mode";
        this.darkModeCheckbox.ThreeState = true;
        this.darkModeCheckbox.UseVisualStyleBackColor = true;
        this.darkModeCheckbox.CheckStateChanged += new System.EventHandler(this.OnDarkModeCheckboxStateChanged);
        
  • Added an event handler for the checkbox's CheckStateChanged event:
    private void OnDarkModeCheckboxStateChanged(object sender, EventArgs e) {
        Theme desiredTheme = darkModeCheckbox.CheckState switch {
            CheckState.Checked       => Theme.Dark,
            CheckState.Unchecked     => Theme.Light,
            CheckState.Indeterminate => Theme.Auto,
            _                        => Theme.Auto
        };
    
        DarkNet.Instance.SetCurrentProcessTheme(desiredTheme);
    }

Screenshots

Dark mode

image

Light mode

image

Auto mode

My Windows user account has its Default App Mode set to Dark in Settings › Personalization › Colors

image

Executable

Download darknet-demo-winforms.zip

@modz2014
Copy link
Author

modz2014 commented Dec 27, 2022

i think there is a bug unless its the version of windows 10 i'm on because the bar does not change color
also i get this erros as well as it needs to be called before the application is started

System.InvalidOperationException: 'Called SetCurrentProcessTheme() too late, call it before any calls to Form.Show(), Window.Show(), Application.Run(), IDarkNet.SetWindowThemeForms(), or IDarkNet.SetWindowThemeWpf()'

@Aldaviva
Copy link
Owner

I've seen that title bar visual glitch before. I forget exactly how I fixed it, but I think it had to do with calling the methods earlier.

You can try calling DarkNet.Instance.SetCurrentProcessTheme(Theme.Auto) at the very beginning of your Main() method, and see if that makes the glitch and InvalidOperationException go away.

@modz2014
Copy link
Author

modz2014 commented Dec 27, 2022

so i need to set the form in dark mode before i can change
color does not change

@modz2014
Copy link
Author

modz2014 commented Dec 27, 2022

this is my Program file

`static void Main()
{
Application.SetCompatibleTextRenderingDefault(defaultValue: false);

        Application.EnableVisualStyles();
        DarkNet.Instance.SetCurrentProcessTheme(Theme.Auto);
        IDarkNet instance = DarkNet.Instance;
        instance.SetCurrentProcessTheme(Theme.Auto);
     
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());
    }`

@Aldaviva
Copy link
Owner

Sorry this is hitting some roadblocks. I will try to take a look soon and see if I can figure out what may be happening and any suggestions I can offer.

@modz2014
Copy link
Author

modz2014 commented Dec 27, 2022

ok no worries seem weird

@modz2014
Copy link
Author

modz2014 commented Dec 30, 2022

hey I was wondering how you went

@Aldaviva
Copy link
Owner

It looks like that demo app I posted has an issue where the subsequent theme changes using the checkbox after first load don't take effect until you blur and refocus the window, and this happens on Windows 10 1809 but not Windows 11 22H2. I think this means the DarkNet library is missing a native DLL call that I didn't understand or seemed superfluous when I was porting the logic from the win32-darkmode example C++ application. I'll need to figure out what method call is missing and when to call it.

@Aldaviva
Copy link
Owner

I believe I've fixed the issue with not being able to repeatedly change the process or window themes after the form has already been shown.

This has been released as version 2.1.0 on NuGet Gallery. The WPF and Windows Forms demo apps have also been updated to show the ability to change the process theme after the window is already visible using a checkbox that cycles between the Dark, Light, and Auto themes.

@Aldaviva Aldaviva added this to the 2.1.0 milestone Mar 3, 2023
@modz2014
Copy link
Author

i can not seem to get it to work when i click on settings from my main form and click on dark mode nothing happens and its already dark mode before i click but not all the groupboxes or anything are in dark mode just the form

@Aldaviva
Copy link
Owner

If the title bar is already dark then that's good, it means this library is working.

Keep in mind that this library does not make the client areas of any windows dark, including controls like groupboxes. It only changes the title bar. You have to style the contents of the window yourself.

You can try changing the groupbox's ForeColor and BackColor based on IDarkNet.EffectiveCurrentProcessThemeIsDark (and change events are emitted from IDarkNet.EffectiveCurrentProcessThemeIsDarkChanged), but I don't know if setting those properties on controls like groupboxes actually works or looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants