vb.netdatetimepickermonthcalendar

How can I disable 'MonthCalendar' and Datetimepicker 's visual style for VB.NET?


enter image description here

I want to fill monthcalendar for my form..

but it didn't work, I figured out the problem is 'Visual style'.

So, I tried Application.VisualStyleState = System.Windows.Forms.VisualStyles.VisualStyleState.NoneEnabled

It works but it makes looking weird my whole program.. ;(

How can I disable only 'MonthCalendar' and Datetimepicker 's visual style? (for VB.NET)

Please, Help me.

Thank you!


Solution

  • You may use SetWindowTheme function to disable the theme for individual controls.

    First, add the following class to your program:

    Imports System.Runtime.InteropServices
    
    Public Class NativeMethods
        <DllImport("uxtheme", ExactSpelling:=True, CharSet:=CharSet.Unicode)>
        Public Shared Function SetWindowTheme(hWnd As IntPtr,
                                              pszSubAppName As String,
                                              pszSubIdList As String) As Integer
        End Function
    End Class
    

    Then, you can simply do something like this:

    NativeMethods.SetWindowTheme(DateTimePicker1.Handle, String.Empty, String.Empty)
    NativeMethods.SetWindowTheme(MonthCalendar1.Handle, String.Empty, String.Empty)
    

    Result:

    Before After
    Before After

    Disabling the theme for the MonthCalendar created by the DateTimePicker is a little trickier. Because DateTimePicker dynamically creates it when you click the dropdown button, you'll have to handle the DropDown event of the DateTimePicker, get the handle of the MonthCalender, and then disable its theme. See this answer for more information.

    Here's an example:

    <DllImport("user32.dll", CharSet:=CharSet.Auto)>
    Public Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As Integer, lParam As Integer) As IntPtr
    End Function
    
    Private Const DTM_GETMONTHCAL As Integer = &H1008
    
    Private Sub DateTimePicker1_DropDown(sender As Object, e As EventArgs) Handles DateTimePicker1.DropDown
        Dim calendarHandle = SendMessage(DateTimePicker1.Handle, DTM_GETMONTHCAL, 0, 0)
        If calendarHandle <> IntPtr.Zero Then
            NativeMethods.SetWindowTheme(calendarHandle, String.Empty, String.Empty)
        End If
    End Sub