Exemplu personalizat de comandă WPF

Am făcut o programare wpf și un lucru pe care nu l-am primit a fost modelul de comandă. Fiecare exemplu pare a fi pentru construit în unul, editați, tăiați, lipiți. Oricine are un exemplu sau sugestie de bune practici pentru comenzile personalizate?

0
fr hi bn

4 răspunsuri

Ah, ha! O întrebare pe care o pot răspunde! În primul rând, trebuie să menționez că mi-a fost mai ușor să definim și să conectăm mai mult comenzile în cod decât în ​​XAML. Ea îmi permite să conectez manageri pentru comenzi mai ușor decât o abordare XAML.

Ar trebui să aflați ce comenzi doriți să aveți și la ce se referă. În aplicația mea, am în prezent o clasă pentru definirea unor comenzi importante de aplicație cum ar fi:

public static class CommandBank
{
  /// Command definition for Closing a window
  public static RoutedUICommand CloseWindow { get; private set; }

  /// Static private constructor, sets up all application wide commands.
  static CommandBank()
  {
    CloseWindow = new RoutedUICommand();
    CloseWindow.InputGestures.Add(new KeyGesture(Key.F4, ModifierKeys.Alt));
   //...
  }

Acum, pentru că am vrut să păstrez codul împreună, folosind o abordare a codului numai pentru Comenzi îmi permite să pun următoarele metode în clasa de mai sus:

/// Closes the window provided as a parameter
public static void CloseWindowExecute(object sender, ExecutedRoutedEventArgs e)
{
  ((Window)e.Parameter).Close();
}

/// Allows a Command to execute if the CommandParameter is not a null value
public static void CanExecuteIfParameterIsNotNull(object sender, CanExecuteRoutedEventArgs e)
{
  e.CanExecute = e.Parameter != null;
  e.Handled = true;
}

Cea de-a doua metodă poate fi împărtășită cu alte comenzi fără a fi nevoie să o repet peste tot.

Odată ce ați definit comenzile de acest fel, le puteți adăuga la orice bucată de interfață. In cele ce urmeaza, odata ce fereastra are Loaded, adaug legaturile de comanda la fereastra si MenuItem si apoi adaug un legare de intrare la fereastra folosind o buclă pentru a face acest lucru pentru toate legaturile de comenzi. Parametrul care este trecut este fereastra sa de sine astfel încât codul de mai sus știe ce fereastră să încerce și să închidă.

public partial class SimpleWindow : Window
{
  private void WindowLoaded(object sender, RoutedEventArgs e)
  {
   //...
    this.CommandBindings.Add(
      new CommandBinding(
        CommandBank.CloseWindow,
        CommandBank.CloseWindowExecute,
        CommandBank.CanExecuteIfParameterIsNotNull));

    foreach (CommandBinding binding in this.CommandBindings)
    {
       RoutedCommand command = (RoutedCommand)binding.Command;
       if (command.InputGestures.Count > 0)
       {
         foreach (InputGesture gesture in command.InputGestures)
         {
           var iBind = new InputBinding(command, gesture);
           iBind.CommandParameter = this;
           this.InputBindings.Add(iBind);
         }
       }
    }

   //menuItemExit is defined in XAML
    menuItemExit.Command = CommandBank.CloseWindow;
    menuItemExit.CommandParameter = this;
   //...
  }

 //....
}

De asemenea, mai târziu am organizat evenimente pentru evenimentele WindowClosing și WindowClosed, vă recomand să faceți ca implementarea reală a comenzilor să fie cât mai mică și mai generică posibil. Ca și în acest caz, nu am încercat să pun cod care încearcă să oprească închiderea ferestrei dacă nu există date nesalvate, am păstrat acel cod ferm în cadrul evenimentului WindowClosing.

Dați-mi voie să știu dacă aveți întrebări ulterioare. :)

0
adăugat
CanExecuteIfParameterIsNotNull conține una dintre neplăcerile mele pentru animale de companie. De ce nu doar e.CanExecute = e.Parametru! = Null;
adăugat autor Ray, sursa
@Ray Asta nu era ceva ce știam că aș putea face! Vă mulțumim pentru editarea lui Drew. :)
adăugat autor Nidonocu, sursa

Lucrul cu XAML este că este bine pentru programele "simple", dar din păcate, nu funcționează bine atunci când doriți să faceți lucruri cum ar fi funcțiile de partajare. Spuneți că aveți mai multe clase și toate UI-urile care au comenzi care nu au fost niciodată dezactivate, va trebui să scrieți o metodă "CanAlwaysExecute" pentru fiecare fereastră sau UserControl! Nu este chiar foarte DRY .

După ce am citit mai multe bloguri și încercând mai multe lucruri, am făcut alegerea de a face XAML pur și simplu despre aspect, stiluri, animații și declanșatoare. Toată mișcarea legată de manipulatorii evenimentului și comandantul este acum în jos în codul din spate. :)

O alta miscare este legata de intrare, pentru a fi prinsi, trebuie sa se concentreze asupra obiectului care contine legaturile de intrare. De exemplu, pentru a avea o scurtă durată, puteți utiliza oricând (de exemplu, F1 pentru a deschide ajutor), că legarea de intrare trebuie să fie setată pe obiectul Window, deoarece întotdeauna se concentrează când aplicația este activă. Utilizarea metodei de cod ar trebui să facă acest lucru mai ușor, chiar și atunci când începeți să utilizați UserControls care ar putea dori să adauge legăturile de intrare la fereastra părinte.

0
adăugat

În ediția din septembrie 2008 a revistei MSDN, Brian Noyes are un articol excelent despre RoutedCommand/RoutedEvents !!!

Here is the link: http://msdn.microsoft.com/en-us/magazine/cc785480.aspx

0
adăugat
Linkul este mort ...
adăugat autor ardila, sursa