2009-06-30 4 views
9

Mi piacerebbe essere in grado di catturare gli eventi DoubleClick o MouseDoubleClick da un pulsante di opzione Winforms standard, ma sembrano nascosti e non funzionano. Al momento ho un codice come questo:Come si ottiene un evento DoubleClick in un pulsante di opzione .NET?

public class RadioButtonWithDoubleClick : RadioButton 
{ 
    public RadioButtonWithDoubleClick() 
     : base() 
    { 
     this.SetStyle(ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true); 
    } 

    [EditorBrowsable(EditorBrowsableState.Always), Browsable(true)] 
    public new event MouseEventHandler MouseDoubleClick; 
    protected override void OnMouseDoubleClick(MouseEventArgs e) 
    { 
     MouseEventHandler temp = MouseDoubleClick; 
     if(temp != null) { 
      temp(this, e); 
     } 
    } 
} 

C'è un modo più semplice e più pulito per farlo?

Edit: per lo sfondo, sono d'accordo con il post di Raymond Chen here che la capacità di fare doppio clic su un pulsante di opzione (se queste sono le unici controlli nella finestra di dialogo) rende la finestra di un pochino più facile da usare per persone che ne sono a conoscenza.

In Vista utilizzando le finestre di dialogo delle attività (vedere this Microsoft guideline page o this MSDN page specifically about the Task Dialog API) sarebbe la soluzione più ovvia, ma non ne abbiamo il lusso.

risposta

10

Sulla base del tuo suggerimento originale I fatto una soluzione senza la necessità di creare una sottoclasse del radiobuton utilizzando la riflessione:

MethodInfo m = typeof(RadioButton).GetMethod("SetStyle", BindingFlags.Instance | BindingFlags.NonPublic); 
if (m != null) 
{ 
    m.Invoke(radioButton1, new object[] { ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true }); 
} 
radioButton1.MouseDoubleClick += radioButton1_MouseDoubleClick; 

Ora l'evento doppio click per il pulsante radio è sparato. BTW: Il suggerimento di Nate che utilizza e.Clicks non funziona. Nei miei test e.Clicks era sempre 1, non importa quanto velocemente o spesso ho fatto clic sul pulsante radio.

3

Si potrebbe fare qualcosa di simile:

myRadioButton.MouseClick += new MouseEventHandler(myRadioButton_MouseClick); 

void myRadioButton_MouseClick(object sender, MouseEventArgs e) 
{ 
    if (e.Clicks == 2) 
    { 
     // Do something 
    } 
} 

Si può o non può decidere anche di verificare che e.Button == MouseButtons.Left

+0

Sono accettare questo, perché anche se penso che la mia soluzione sia più semplice per il mio caso, dove userò lo stesso controllo molte volte, se qualcuno ne volesse uno o due, allora il tuo è molto più semplice. – Ant

+2

Sembra che non funzioni su .NET 3.5 poiché i Clic == 2 non si verificano mai. – Wernight

+0

Non succede nemmeno in .NET 4.0, quindi sto passando la risposta accettata a quella basata sulla riflessione di MSW. – Ant

0

Siamo spiacenti, non hanno la reputazione di commentare su questo. Quale azione stai cercando di fare il doppio clic per l'utente? Penso che l'uso di un doppio clic possa confondere perché è diverso dal modello mentale generale che un utente ha di un pulsante radio (IE singolo clic, selezionare un'opzione da un set)

+0

Buon punto. Aggiornerò la domanda – Ant

+0

Ah, capisco. Stai usando il doppio clic come scorciatoia per selezionare + successivo. Ciò ha senso. Penso che il codice che hai presentato sia il modo più pulito per farlo. Sembra che questa sia la funzionalità che MS ha cercato di seppellire intenzionalmente per il radiobutton. – Ehz

+0

Questo è quello che ho capito :(Grazie per il feedback. – Ant

1

in base alla risposta @MSW, ho fatto questa classe estensione:

static class RadioButtonEx 
{ 
    public static void AllowDoubleClick(this RadioButton rb, MouseEventHandler MouseDoubleClick) 
    { 
     // 
     // Allow double clicking of radios 
     System.Reflection.MethodInfo m = typeof(RadioButton).GetMethod("SetStyle", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); 
     if (m != null) 
      m.Invoke(rb, new object[] { ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true }); 

     rb.MouseDoubleClick += MouseDoubleClick; 
    } 
} 

che viene poi super facile da impostare e riutilizzo:

radioButton.AllowDoubleClick((a, b) => myDoubleClickAction());