C# Winform DateTimePicker 字型/視窗 大小 控制設定 [建立自定義UI元件]
C# Winform DateTimePicker 字型/視窗 大小 控制設定 [建立自定義UI元件]
資料來源:
https://stackoverflow.com/questions/48020286/is-it-possible-to-increase-size-of-calendar-popup-in-winform
https://blog.csdn.net/QinYHJ/article/details/124841156
https://rjcodeadvance.com/custom-datetimepicker-custom-controls-winform-c/
https://www.youtube.com/watch?v=IJM9SIX0pIs
code01:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices;//C# 呼叫 DLL API namespace CS_VPOS { //https://stackoverflow.com/questions/48020286/is-it-possible-to-increase-size-of-calendar-popup-in-winform //https://blog.csdn.net/QinYHJ/article/details/124841156 public class MyDateTimePicker : DateTimePicker { private const int SWP_NOMOVE = 0x0002; private const int DTM_First = 0x1000; private const int DTM_GETMONTHCAL = DTM_First + 8; private const int MCM_GETMINREQRECT = DTM_First + 9; [DllImport("uxtheme.dll")] private static extern int SetWindowTheme(IntPtr hWnd, string appName, string idList); [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, ref RECT lParam); [DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); [DllImport("User32.dll")] private static extern IntPtr GetParent(IntPtr hWnd); [StructLayout(LayoutKind.Sequential)] private struct RECT { public int L, T, R, B; } protected override void OnDropDown(EventArgs eventargs) { //添加后编译程序,在要使用的界面拖动用户控件使用即可,弹出窗口的大小会根据CalendarFont决定 var hwndCalendar = SendMessage(this.Handle, DTM_GETMONTHCAL, 0, 0); SetWindowTheme(hwndCalendar, string.Empty, string.Empty); var r = new RECT(); SendMessage(hwndCalendar, MCM_GETMINREQRECT, 0, ref r); var hwndDropDown = GetParent(hwndCalendar); SetWindowPos(hwndDropDown, IntPtr.Zero, 0, 0, r.R - r.L + 6, r.B - r.T + 6, SWP_NOMOVE); base.OnDropDown(eventargs); } } }
code02:
using System; using System.Collections.Generic; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; //https://rjcodeadvance.com/custom-datetimepicker-custom-controls-winform-c/ //https://www.youtube.com/watch?v=IJM9SIX0pIs //https://stackoverflow.com/questions/48020286/is-it-possible-to-increase-size-of-calendar-popup-in-winform //https://blog.csdn.net/QinYHJ/article/details/124841156 namespace CS_VPOS { public class RJDatePicker : DateTimePicker { //Fields //-> Appearance private Color skinColor = Color.MediumSlateBlue; private Color textColor = Color.White; private Color borderColor = Color.PaleVioletRed; private int borderSize = 0; //-> Other Values private bool droppedDown = false; private Image calendarIcon = Properties.Resources.calendarWhite; private RectangleF iconButtonArea; private const int calendarIconWidth = 34; private const int arrowIconWidth = 17; //Properties public Color SkinColor { get { return skinColor; } set { skinColor = value; if (skinColor.GetBrightness() >= 0.8F) calendarIcon = Properties.Resources.calendarDark; else calendarIcon = Properties.Resources.calendarWhite; this.Invalidate(); } } public Color TextColor { get { return textColor; } set { textColor = value; this.Invalidate(); } } public Color BorderColor { get { return borderColor; } set { borderColor = value; this.Invalidate(); } } public int BorderSize { get { return borderSize; } set { borderSize = value; this.Invalidate(); } } //Constructor public RJDatePicker() { this.SetStyle(ControlStyles.UserPaint, true); this.MinimumSize = new Size(0, 35); this.Font = new Font(this.Font.Name, 9.5F); } //Overridden methods /* protected override void OnDropDown(EventArgs eventargs) { base.OnDropDown(eventargs); droppedDown = true; } */ private const int SWP_NOMOVE = 0x0002; private const int DTM_First = 0x1000; private const int DTM_GETMONTHCAL = DTM_First + 8; private const int MCM_GETMINREQRECT = DTM_First + 9; [DllImport("uxtheme.dll")] private static extern int SetWindowTheme(IntPtr hWnd, string appName, string idList); [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, ref RECT lParam); [DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); [DllImport("User32.dll")] private static extern IntPtr GetParent(IntPtr hWnd); [StructLayout(LayoutKind.Sequential)] private struct RECT { public int L, T, R, B; } protected override void OnDropDown(EventArgs eventargs) { //添加后编译程序,在要使用的界面拖动用户控件使用即可,弹出窗口的大小会根据CalendarFont决定 var hwndCalendar = SendMessage(this.Handle, DTM_GETMONTHCAL, 0, 0); SetWindowTheme(hwndCalendar, string.Empty, string.Empty); var r = new RECT(); SendMessage(hwndCalendar, MCM_GETMINREQRECT, 0, ref r); var hwndDropDown = GetParent(hwndCalendar); SetWindowPos(hwndDropDown, IntPtr.Zero, 0, 0, r.R - r.L + 6, r.B - r.T + 6, SWP_NOMOVE); base.OnDropDown(eventargs); } protected override void OnCloseUp(EventArgs eventargs) { base.OnCloseUp(eventargs); droppedDown = false; } protected override void OnKeyPress(KeyPressEventArgs e) { base.OnKeyPress(e); e.Handled = true; } protected override void OnPaint(PaintEventArgs e) { using (Graphics graphics = this.CreateGraphics()) using (Pen penBorder = new Pen(borderColor, borderSize)) using (SolidBrush skinBrush = new SolidBrush(skinColor)) using (SolidBrush openIconBrush = new SolidBrush(Color.FromArgb(50, 64, 64, 64))) using (SolidBrush textBrush = new SolidBrush(textColor)) using (StringFormat textFormat = new StringFormat()) { RectangleF clientArea = new RectangleF(0, 0, this.Width - 0.5F, this.Height - 0.5F); RectangleF iconArea = new RectangleF(clientArea.Width - calendarIconWidth, 0, calendarIconWidth, clientArea.Height); penBorder.Alignment = PenAlignment.Inset; textFormat.LineAlignment = StringAlignment.Center; //Draw surface graphics.FillRectangle(skinBrush, clientArea); //Draw text graphics.DrawString(" " + this.Text, this.Font, textBrush, clientArea, textFormat); //Draw open calendar icon highlight if (droppedDown == true) graphics.FillRectangle(openIconBrush, iconArea); //Draw border if (borderSize >= 1) graphics.DrawRectangle(penBorder, clientArea.X, clientArea.Y, clientArea.Width, clientArea.Height); //Draw icon graphics.DrawImage(calendarIcon, this.Width - calendarIcon.Width - 9, (this.Height - calendarIcon.Height) / 2); } } protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); int iconWidth = GetIconButtonWidth(); iconButtonArea = new RectangleF(this.Width - iconWidth, 0, iconWidth, this.Height); } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (iconButtonArea.Contains(e.Location)) this.Cursor = Cursors.Hand; else this.Cursor = Cursors.Default; } //Private methods private int GetIconButtonWidth() { int textWidh = TextRenderer.MeasureText(this.Text, this.Font).Width; if (textWidh <= this.Width - (calendarIconWidth + 20)) return calendarIconWidth; else return arrowIconWidth; } } }