2009-06-22 1 views
8

Quando si aggiunge un controllo DateTimePicker, è possibile selezionare parte del valore di controllo (ad esempio il mese) e quindi utilizzare le frecce su/giù per modificare questa parte della data/valore temporale (ad esempio, incrementare/decrementare il mese).Come rendere un incremento/decremento DateTimePicker sulla rotellina del mouse

Quello che mi piacerebbe fare è consentire la stessa cosa con la rotellina del mouse. Ho provato a registrarmi sull'evento MouseWheel ma non riesco a trovare un modo per sapere quale parte della mia data/ora è attualmente selezionata, quindi non ho modo di sapere se dovrei incrementare il tempo, il giorno, il mese o il anno.

C'è un modo per farlo?

risposta

11

Una possibile soluzione, ma non del tutto elegante, sarebbe qualcosa di simile:

private void dateTimePicker1_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e) 
{ 
    if (e.Delta > 0) 
    { 
     System.Windows.Forms.SendKeys.Send("{UP}"); 
    } 
    else 
    { 
     System.Windows.Forms.SendKeys.Send("{DOWN}"); 
    } 
} 

questo dovrebbe funzionare in generale, ma alcuni casi angolari potrebbero avere risultati imprevisti (come avere eventi KeyUp/KeyDown sovrascritti)

+0

Grazie mille. In realtà stavo provando qualcosa del genere io stesso, con un controllo utente ereditato da DateTimePicker, ma non sapevo come inviare un evento all'interno del gestore di eventi MouseWheel (ho provato questo.OnKeyDown, ma non ho ottenuto alcun risultato). – Ksempac

+0

Il mondo è stato capovolto 4 anni fa o è capovolto ora? Ho girato la funzione per ottenere valori più alti quando si scorre verso il basso. – Bitterblue

0
dateTimePicker1.MouseWheel += new MouseEventHandler(dateTimePicker1_MouseWheel); 

    private void dateTimePicker1_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e) 
    { 
     int incrementValue = SystemInformation.MouseWheelScrollLines; 
     //Do increment 
    } 

Riferimento: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mousewheel.aspx

+0

No, non hai risposto alla mia domanda. So come ottenere l'incremento (e.Delta è abbastanza per me). So anche dove è il cursore (e.Location) se ne ho bisogno. Quello che ho bisogno di sapere è quale parte della mia data è attualmente selezionata. Ad esempio, se la mia data è AAAA MM DD, ho bisogno di sapere se l'utente ha selezionato MM, GG, o AAAA, in modo da poterlo incrementare. Ad esempio, in una casella di testo, è possibile ottenere l'inizio e la lunghezza della selezione. Oppure c'è una funzione che ti dà l'indice più vicino alla posizione del tuo cursore. Non ho pensato niente del genere per DateTimePicker. – Ksempac

+0

Scusa non ho bevuto il mio caffè e ho letto solo il titolo;). – Fiur

0

Se si imposta la proprietà su True ShowUpDown si ottiene una casella di selezione piuttosto che un menu a discesa e questo modifica la parte evidenziata della data. Anche se ho appena scoperto che questo è irrilevante in quanto i tasti freccia su e giù alterano la parte evidenziata della data indipendentemente dal fatto che questa proprietà sia impostata su true o no.

Se riesci a trovare questo codice dovresti essere in grado di far funzionare anche la rotellina del mouse. Dare un'occhiata e vedere cosa riesco a trovare.

UPDATE:

ho appena trovato questa nota sulla ShowCheckBox immobile:

lettura/scrittura. Se true, una casella di controllo è visualizzata a sinistra del valore di data nel controllo. Quando questa casella di controllo è selezionata, i valori nel controllo possono essere modificati dall'utente al runtime evidenziando una parte di la data e premendo i tasti freccia. Se non selezionato, la data può essere modificata solo da facendo clic sul menu a discesa per visualizzare il calendario. L'impostazione predefinita è false.

È utile?

UPDATE 2:

io non sono stato in grado di trovare qualsiasi codice che si occupa di questo particolare aspetto del DateTimePicker. Microsoft non rilascia più il codice per questo tipo di controlli?

+0

No, ho già impostato ShowCheckBox su true (perché ho bisogno della casella di controllo). Quindi, come ho detto, posso modificare i valori con le frecce su/giù. Quello che voglio fare ora è avere lo stesso comportamento con la rotella del mouse (usare up/down è piuttosto frustrante). Il problema è che posso trovare un modo per ottenere quale parte del mio controllo è evidenziata. – Ksempac

+0

Sto usando .NET on e off per soli 2 anni, ma non ho mai visto alcun codice interno da Microsoft. Tutto quello che ho visto sono alcuni esempi su come usano l'API che offrono. Se vuoi attuare il tuo comportamento, spetta a te capire la "magia" che dovresti usare. – Ksempac

+0

@Ksempac: di nuovo nel passato oscuro e visuale di Visual C++ e MFC, era possibile ottenere alcuni dei codici sorgente MFC, uno strumento inestimabile nell'aiutare a lavorare. Sembra che MS abbia interrotto questa pratica con C#, a meno che non l'abbia ancora trovato. – ChrisF

0

non sono sicuro, ma è questa direzione ogni bene ..

Isnt sicuro che, coordinata x per il mese < x per il giorno < x per l'anno (supponendo che non formato personalizzato) all'interno del controllo DatePicker, come il suo visualizzato lungo l'asse x

quindi forse possiamo catturare l'evento dateTimePicker1_MouseDown e impostare il coord x su cui abbiamo fatto clic prima di scorrere verso una variabile dire: xCordOfClick, e quindi usare questo nel codice di Fiur per la rotellina del mouse per incrementare in base al differenza in dove abbiamo cliccato e la posizione x del datepicker.

qualcosa come

In dateTimePicker1_MouseDown (object sender, MouseEventArgs e)

{ 
     xCordOfClick = e.X; 
    } 

Nel caso in rotella del mouse

{ 
     //Do increment based on how far we clicked from the location of the control 
     // increment based on (xCordOfClick - dateTimePicker1.Location.X).ToString()); 
    } 
+0

Io uso un formato personalizzato, ma non è un problema, dal momento che io sono quello che lo imposta. Ho pensato a qualcosa del genere ma vorrei evitarlo dato che si basa su presupposti come le dimensioni della polizia o il formato utilizzato per determinare quanto siamo nel controllo. – Ksempac

+0

Sono d'accordo, è un modo grossolano di farlo, più simile al mondo dello schermo di demolizione :) .. bella domanda però –

2

Ho provato a capire anche questo. Alla fine, ho finito con questo:

Private Sub dtpDateTimePicker_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) 
    If e.Delta > 0 Then 
     SendKeys.Send("{Up}") 
    Else 
     SendKeys.Send("{Down}") 
    End If 
End Sub 

È possibile aggiungere automaticamente questo gestore a tutti la data di raccoglitori nel modulo ed è contenitori utilizzando questo metodo. Basta chiamare una volta in form_load:

Public Sub AttachDateTimeMouseWheels(ByRef ownerForm As Control) 

    Dim myControl As Control   

    For Each myControl In ownerForm.Controls 

     If TypeOf myControl Is DateTimePicker Then 
      AddHandler myControl.MouseWheel, AddressOf dtpDateTimePicker_MouseWheel 
     Else 
      If myControl.Controls.Count > 0 Then 
       AttachDateTimeMouseWheels(myControl) 
      End If 
     End If 

    Next 

End Sub 
1

Usa WM_KEYDOWN sendmessage/WM_KEYUP

Private Sub DateTimePickerAlarm_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DateTimePickerAlarm.MouseWheel 
     If e.Delta > 0 Then 
      Native.User32.SendMessage(DateTimePickerAlarm.Handle, &H100, Keys.Up, &H1480001) 
      Native.User32.SendMessage(DateTimePickerAlarm.Handle, &H101, Keys.Up, &HC1480001) 
     Else 
      Native.User32.SendMessage(DateTimePickerAlarm.Handle, &H100, Keys.Down, &H1500001) 
      Native.User32.SendMessage(DateTimePickerAlarm.Handle, &H101, Keys.Down, &HC1500001) 
     End If 
     'msg=0x100 (WM_KEYDOWN) hwnd=0x???????? wparam=0x26 lparam=0x01480001 result=0x0 
     'msg=0x101 (WM_KEYUP) hwnd=0x???????? wparam=0x26 lparam=0xc1480001 result=0x0 
     'msg=0x100 (WM_KEYDOWN) hwnd=0x???????? wparam=0x28 lparam=0x01500001 result=0x0 
     'msg=0x101 (WM_KEYUP) hwnd=0x???????? wparam=0x28 lparam=0xc1500001 result=0x0 
    End Sub