2012-09-12 22 views
5

Attualmente ho un'applicazione C# winforms con Ctrl + C e Ctrl + V vincolata come scorciatoie da tastiera nel menu principale Modifica. Esiste un comportamento di copia/incolla personalizzato all'interno del codice che risponde a queste voci di menu, come ad esempio copiare e incollare righe in listview.Comportamento copia/incolla personalizzato con C# winforms mentre consente la modifica del testo copia/incolla

Tuttavia, il mio problema è che è possibile modificare il testo all'interno di una riga, e quando si esegue questa operazione, desidero Ctrl + C e Ctrl + V per non attivare il comando del menu di modifica e preferire la normale copia di testo /incolla.

Una cosa che ho provato è l'attivazione degli eventi BeforeLabelEdit e AfterLabelEdit e la disabilitazione/riattivazione manuale degli elementi del menu dall'interno. Sfortunatamente, sembra che una scorciatoia da tastiera su una voce di menu disabilitata attiva ancora l'evento menu_Popup, che è attualmente utilizzato per decidere quali voci di menu devono essere abilitate/disabilitate. (Ad esempio, "Incolla" è attivo solo se c'è un testo negli Appunti). Quindi, anche se disattivo la voce di menu, la scorciatoia da tastiera attiverà comunque l'evento Popup, che riabiliterà la voce di menu. (Si tratta di un bug?)

Non riesco a trovare alcun metodo per disabilitare temporaneamente una scorciatoia da tastiera di voci di menu senza memorizzare manualmente la vecchia scorciatoia, impostare il collegamento su null, quindi copiarlo quando devo riattivarlo (che si sente sporco).

Sicuramente ignorare il comportamento di copia/incolla o aggiungervi, è una cosa comune da fare? C'è un modello migliore da usare qui?

+0

Ovveriding copia incolla suona come una cattiva idea per me. sono abituato a 'copia/incolla', funziona sempre allo stesso modo su tutte le app. la tua app mi confonderà. ma se insisti, perché non controllare la messa a fuoco? se lo stato attivo è sulla casella di testo, eseguire una copia incolla se non si esegue l'altra – Nahum

+0

Il comportamento di copia/incolla personalizzato si occupa solo di copiare e incollare le righe quando non si modifica il testo.Voglio il comportamento predefinito di copia/incolla quando si modifica il testo. –

+2

Cancellare il tasto di scelta rapida del menu è il modo più semplice. Altre alternative saranno "più sporche". –

risposta

0

Sembra che sia necessario utilizzare un livello inferiore rispetto a C# se si desidera sostituire il comportamento predefinito di copia/incolla (vedere Clipboard event C# e Detect & Differentiate Clipboard Events (Cut,Copy and Paste)). Tuttavia, forse potresti mettere la tua logica dietro una "guardia" che sa come indirizzare una richiesta di azione (come la "Copia") e poi ridirigerla come approprite.

Ecco una lezione di prova:

namespace Your.App 
{ 
    public class GuardedCommand 
    { 
     public bool CurrentlyEditing { get; set; } 
     public GuardedCommand() 
     { 
      CurrentlyEditing = false; 
     } 
     public void DoCopy() 
     { 
      if(CurrentlyEditing) 
       StandardCopyCommand(); 
      else 
       ShortcutCopyCommand(); 
     } 
     void ShortcutCopyCommand() { /*menu work here (or delegate to another class)*/ } 
     void StandardCopyCommand() { /*"normal" work here (or delegate again)*/ } 
    } 
} 

Per utilizzare si dovrebbe creare la classe, quindi impostare è guardedCommand.CurrentlyEditing proprietà come appropriato nei BeforeLabelEdit e AfterLabelEdit eventi. Quindi, ogni volta che prendi la scorciatoia CTRL + C, invoca semplicemente guardedCommand.DoCopy() e si occuperà del resto.

Se stai cercando di leggere un modello per quello che stai cercando di fare, controlla lo State Pattern, che il codice precedente è una sorta di implementazione e di. Per essere un modello di stato (o strategia) reale, è necessario disporre di classi concrete separate che implementino DoCopy() e DoPaste() anziché utilizzare solo if/else o switch. Quindi, quando viene modificato CurrentlyEditing, l'implementazione concreta corretta viene impostata come classe corrente utilizzata per gestire il metodo DoCopy().

E solo perché mi c'è voluto più tempo per scrivere che il paragrafo di quello che avrebbe dovuto solo dare un codice, ecco qualche codice:

namespace Your.App 
{ 
//correct implementation of the State Pattern 
    interface IClipboard 
    { 
     void Copy(); 
     void Paste(); 
    } 
    class MyCustomClipboard : IClipboard 
    { 
     public void Copy() { /*your special code*/ } 
     public void Paste() { /*your code again*/ } 
    } 
    class DefaultClipboard : IClipboard 
    { 
     public void Copy() { /*default code*/ } 
     public void Paste() { /*default code again*/ } 
    } 
    public class StateClass 
    { 
     IClipboard State { get; set; } 
     public StateClass() 
     { 
      CurrentlyEditing = false; 
     } 
     bool _currentlyEditing; 
     public bool CurrentlyEditing 
     { 
      get { return _currentlyEditing; } 
      set 
      { 
       _currentlyEditing = value; 
       if(_currentlyEditing) 
        State = new DefaultClipboard(); 
       else 
        State = new MyCustomClipboard(); 
      } 
     } 
     public void Copy() 
     { 
      State.Copy(); 
     } 
     public void Paste() 
     { 
      State.Paste(); 
     } 
    } 
} 

Come si può vedere, questo può essere un po 'eccessivo quando c'è sono solo due stati (e il numero di stati probabilmente non aumenterà).

+0

Ciò significa che avrei bisogno di codificare il comportamento predefinito di copia/incolla da solo? Questo è qualcosa che speravo di evitare. Inoltre, questo significa che non sarei in grado di elencare i comandi sul menu nella colonna dei tasti di scelta rapida sulla destra? Quello che mi sorprende è che, per impostazione predefinita, il metodo KeyDown non cattura Ctrl + C quando sto modificando un'etichetta, ma lo fa quando non lo sto modificando (che è utile). Si tratta di un comportamento diverso rispetto ai tasti di scelta rapida del menu, che, se assegnati, attiveranno se sto modificando o meno. –

+0

Siamo spiacenti, per qualche motivo ho avuto l'impressione che avessi il codice per utilizzare la copia/incolla predefinita già implementata. Dopo aver riletto la tua domanda, vedo che non ne parli mai. Sospetto che la soluzione "migliore" sia un'implementazione del modello Stato (o [Strategia] (http://en.wikipedia.org/wiki/Strategia_pattern)) che si occupa di impostare e cancellare le scorciatoie per te come @John menzionato, a seconda dello stato in cui ti trovi/della strategia che desideri utilizzare. –

Problemi correlati