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;
}
}
}