开发者

Open DateTimePicker C# control programmatically

开发者 https://www.devze.com 2022-12-22 12:21 出处:网络
How can I open the DateTimePicker C# control programmatically? I want to show the Calendar in the Datetime Picker control by sending keys to the control.

How can I open the DateTimePicker C# control programmatically? I want to show the Calendar in the Datetime Picker control by sending keys to the control. Is there a way we开发者_JAVA技巧 can do that?


Try the following

//part of the usings
using System.Runtime.InteropServices;

//declares
[DllImport("user32.dll")]
private static extern bool PostMessage(
IntPtr hWnd, // handle to destination window
Int32 msg, // message
Int32 wParam, // first message parameter
Int32 lParam // second message parameter
);

const Int32 WM_LBUTTONDOWN = 0x0201;

//method to call dropdown
private void button1_Click(object sender, EventArgs e)
{
    Int32 x = dateTimePicker1.Width - 10;
    Int32 y = dateTimePicker1.Height / 2;
    Int32 lParam = x + y * 0x00010000;

    PostMessage(dateTimePicker1.Handle, WM_LBUTTONDOWN, 1,lParam);

}


On my system (Windows 7, .NET 35) the other solutions did not work. I found another solution on a MS discussion site that did work.

using System.Runtime.InteropServices;

public static class Extensions
{
    [DllImport("user32.dll", SetLastError = true)]
    private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

    private const uint WM_SYSKEYDOWN = 0x104;

    public static void Open(this DateTimePicker obj)
    {
        SendMessage(obj.Handle, WM_SYSKEYDOWN, (int)Keys.Down, 0);
    }
}

Source : http://social.msdn.microsoft.com/Forums/windows/en-US/f2f0b213-d57a-46de-b924-e21b7ac0882e/programmatically-open-the-calendar-of-the-datetimepicker-control?forum=winforms

Usage:

dateTimePicker1.Open();

Warnings. This will not work if the dateTimePicker1 is a Control on DataGridView (ie if you try to make a pop-up DatePicker on the DGV). It does work if the Control is added to the Form instead. What will happen is that the synthesized cursor "down" event will be swallowed by the DGV, and will move the current cell pointer down one instead of drop-drop the Calendar of the DTP.


Source: https://social.msdn.microsoft.com/Forums/windows/en-US/f2f0b213-d57a-46de-b924-e21b7ac0882e/programmatically-open-the-calendar-of-the-datetimepicker-control?forum=winforms Refer answer by David M Morton https://social.msdn.microsoft.com/profile/david%20m%20morton/?ws=usercard-mini

//DateTimePicker dtpicker
dtpicker.Select();
SendKeys.Send("%{DOWN}");

"%{DOWN}" Key combination - Alt key(%) +Down arrow code to programmatically trigger key down event for datetimepicker (particularly the event of click on the dropdown arrow in a datetimepicker)


Credit goes to astander for providing the solution, which makes a very nice extension:

using System.Linq;
using System.Runtime.InteropServices;

public static class Extensions {

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
  private static extern int PostMessage(IntPtr hwnd, Int32 wMsg, Int32 wParam, Int32 lParam);

  public static void Open(this DateTimePicker obj) {
    const int WM_LBUTTONDOWN = 0x0201;
    int width = obj.Width - 10;
    int height = obj.Height / 2;
    int lParam = width + height * 0x00010000; // VooDoo to shift height
    PostMessage(obj.Handle, WM_LBUTTONDOWN, 1, lParam);
  }

}

Usage:

dateTimePicker1.Open();

This way, you can reuse your Extension anytime you'd like, over and over, in any form using any DateTimePicker control.


The accepted answer is mostly correct, however you should also use:

PostMessage(dateTimePicker1.Handle, WM_LBUTTONUP, 1,lParam);

After posting the WM_LBUTTONDOWN event.

Also, obviously WM_LBUTTONUP must be previously defined:

const Int32 WM_LBUTTONUP = 0x0202;

So my answer is:

using System.Runtime.InteropServices;

//declares
[DllImport("user32.dll")]
private static extern bool PostMessage(
IntPtr hWnd, // handle to destination window
Int32 msg, // message
Int32 wParam, // first message parameter
Int32 lParam // second message parameter
);

const Int32 WM_LBUTTONDOWN = 0x0201;
const Int32 WM_LBUTTONUP = 0x0202;

//method to call dropdown
private void button1_Click(object sender, EventArgs e)
{
    Int32 x = dateTimePicker1.Width - 10;
    Int32 y = dateTimePicker1.Height / 2;
    Int32 lParam = x + y * 0x00010000;

    PostMessage(dateTimePicker1.Handle, WM_LBUTTONDOWN, 1,lParam);
    PostMessage(dateTimePicker1.Handle, WM_LBUTTONUP, 1,lParam);
}

This avoids Mark Lakata's bug in Windows 7 and/or .NET 3.5.

The reasoning is simple: the original code simulates a mouse button down event, but doesn't get the mouse button up again as we would when we click the button.

In that regard, you can try it out yourself: if you press the left mouse button to open a DateTimePicker and don't release the button, you also won't be able to use the control.

Edit: Adapting jp2code's answer:

using System.Runtime.InteropServices;

public static class Extensions {

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
  private static extern int PostMessage(IntPtr hwnd, Int32 wMsg, Int32 wParam, Int32 lParam);

  public static void Open(this DateTimePicker obj) {
    const int WM_LBUTTONDOWN = 0x0201;
    const int WM_LBUTTONUP = 0x0202;
    int width = obj.Width - 10;
    int height = obj.Height / 2;
    int lParam = width + height * 0x00010000; // VooDoo to shift height
    PostMessage(obj.Handle, WM_LBUTTONDOWN, 1, lParam);
    PostMessage(obj.Handle, WM_LBUTTONUP, 1, lParam);
  }

}


I liked some of the previous ideas and finished with this (tested) Mix:

public static class Extensions {

    public static void Open(this DateTimePicker obj)
    {
        obj.Select();
        SendKeys.Send("%{DOWN}");
    }
}

Usage:

dateTimePicker1.Open();    
dateTimePicker2.Open();
0

精彩评论

暂无评论...
验证码 换一张
取 消