2009-06-17 2 views
5

Ammetto che è un po 'minuscolo, ma sto cercando modi migliori per fare i seguenti blocchi di codice. Essi dovrebbero essere auto spiegando ...C# EventHandler Beautiful Code (How To?)

private void listBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
    { 
     var listBoxItem = sender as ListBoxItem; 
     if (listBoxItem != null) 
     { 
      var clickObject = listBoxItem.DataContext as ClickObject; 
      if (clickObject != null) 
      { 
       clickObject.SingleClick(); 
      } 
     } 
    } 

Un altro brutto:

private void listBox_SelectionChangedA(object sender, SelectionChangedEventArgs e) 
    { 
     var lB = sender as ListBox; 
     if (lB != null) 
      StatusBoxA.Text = "Elements selected" + lB.SelectedItems.Count; 
    } 

Sì, lo so, la sua non-morte-urgente. Ma non mi piace il (if! = Null). Tutte le idee magiche per accorciare ancora di più :-)

Btw, ho trovato qualche bella informazioni su un argomento simile: Loops on Null Items bello leggere ...

risposta

3
private void listBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
{ 
     var listBoxItem = sender as ListBoxItem; 
     if (listBoxItem == null) return; 

     var clickObject = listBoxItem.DataContext as ClickObject; 
     if (clickObject == null) return; 

     clickObject.SingleClick(); 
} 
+1

Sembra molto più bello del mio codice :-) –

0

forse sono solo di essere pedante, ma perché avete bisogno per trasmettere il mittente se si sta utilizzando l'evento nel codice del contenitore host.

Indipendentemente da chi ha apportato la modifica a un elenco, non potevi semplicemente dare un nome al listbox e utilizzarlo.

<ListBox x:Name="listbox1" /> 

private void listBox_SelectionChangedA(object sender, SelectionChangedEventArgs e) 
{ 
    StatusBoxA.Text = "Elements selected" + listbox1.SelectedItems.Count; 
} 

Oppure si potrebbe anche ottenere un po 'di questo utilizzando l'associazione senza codice dietro.

+0

L'unico scopo di questa domanda è hairsplitting :-) Ma anche una buona idea, saranno considerati in ulteriori programmazione. Per essere onesti, penso di essere vicino alle buone pratiche, ma non lo saprai mai ... –

0

questo dovrebbe essere lo stesso come il primo, riformattato un po ':

private void listBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    ClickObject clickObject; 
    if (
     ((sender as ListBoxItem) != null) && 
     ((clickObject = ((ListBoxItem)sender).DataContext as ClickObject) != null) 
     ) 
    { 
     clickObject.SingleClick(); 
    } 
} 
0

È possibile aggiungere i metodi di estensioni per formare elementi, che possono poi innescare gli eventi:

public static void OnSelectionChanged(this ListBox b, Action<ListBox> a) 
{ 
    b.SelectedIndexChanged += (s,e) => 
    { 
     if (s is ListBox) 
      a(s as ListBox);   
    }; 
} 
2

one-liner:

private void listBox_SelectionChangedA(object sender, SelectionChangedEventArgs e) 
{ 
    As<ListBox>(sender, (lB) => StatusBoxA.Text = "Elements selected" + lB.SelectedItems.Count); 
} 

o, nidificato:

private void listBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    As<ListBoxItem>(sender, (listBoxItem) => { 
     As<ClickObject>(listBoxItem.DataContext, 
      (clickObject) => clickObject.SingleClick()); 
    }; 
} 

di utilizzare questo metodo generico statico (T è il tipo di destinazione, di ingresso è oggetto da lanciare, il codice è un delegato (o espressione lambda) per eseguire in caso di successo:

static void As<T>(object input, Action<T> code) where T : class 
{ 
    T foo = input as T; 
    if (foo != null) 
    code(foo); 
} 
+0

Mi picchiato :) –

+0

Un approccio interessante ... Un po 'sofisticato per questo esempio (non sapevo nemmeno che questo è possibile) ma sicuramente bello da sapere !! –

8

amo buono, pulito codice ma nella maggior parte dei casi, pulito & elegante non significa breve e intelligente. La brevità del codice è buona per le competizioni. Cambiare un'istruzione "se non nulla" in una foreach potrebbe sembrare molto più interessante, ma è più difficile per tutti gli altri che lavorano nel progetto capire cosa stai cercando di realizzare. Credimi, anche se non te ne ricorderai qualche mese dopo: P. Il tuo codice va bene così com'è!

+1

+1 Questa è una risposta fantastica. –

1

Dato che si utilizzano eventi noti dal framework .NET (a differenza di una terza parte) e dal codice sembra che si stiano utilizzando solo quei metodi per classi specifiche (ad es. ListBoxItems e ListBox), ci sono alcune cose che sai siano vere:

  • sender sarà mai nulla
  • sender sarà sempre un ListBoxItem o ListBox rispettivamente

Quindi perché utilizzare l'operatore as? Solo cast!

Poi il primo frammento diviene

private void listBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
{ 
     var listBoxItem = (ListBoxItem)sender; 
     var clickObject = (ClickObject)listBoxItem.DataContext; 
     clickObject.SingleClick(); 
} 

Nota questo non è vero nel caso generale (che non si farebbe questo se si stesse gestione di tutti gli eventi in PreviewMouseDown che un gestore per tutti i tipi di controllo), ma per il codice di gestione degli eventi come questo, specialmente nel codice dell'interfaccia utente, puoi essere certo quanto puoi essere di qualsiasi cosa, che il mittente non sarà nullo e che il mittente sarà del tipo che ti aspetti.

0

Utilizzando la stessa idea di soluzione Utaal, ma come un metodo di estensione ...

public static void As<TSource>(this object item, Action<TSource> action) where TSource : class 
{ 
    var cast = item as TSource; 

    if (cast != null) 
     action(cast); 
} 

private void listBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    sender.As<ListBoxItem>(listBoxItem => 
     listBoxItem.DataContext.As<ClickObject>(clickObject => 
      clickObject.SingleClick())); 
}