2009-06-17 18 views
5

Lo admito, es un poco pequeño, pero estoy buscando mejores formas de hacer los siguientes bloques de código. Ellos deben ser auto explicar ...C# EventHandler Beautiful Code (¿Cómo?)

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(); 
      } 
     } 
    } 

Otra fea:

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 sé, no es cercana a la muerte-urgente. Pero NO me gusta el (si! = Nulo). Cualquier ideas mágicas para acortar aún más :-)

Por cierto, he encontrado algunas buenas información sobre un tema similar: Loops on Null Items agradable de leer ...

Respuesta

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

Parece mucho mejor que mi código :-) –

0

Tal vez estoy siendo pedante, pero ¿por qué necesita para enviar el remitente si está utilizando el evento dentro de su código de contenedor de host.

Independientemente de quién hizo el cambio en una lista, ¿no podría simplemente darle un nombre a su lista y usar eso.

<ListBox x:Name="listbox1" /> 

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

O incluso podría lograr algo de esto utilizando un enlace sin código.

+0

El único propósito de esta pregunta es hairsplitting :-) Pero también buena idea, se tendrán en cuenta en mayor programación. Para ser sincero, creo que estoy cerca de las buenas prácticas, pero nunca lo sabrás ... –

0

Esto se supone que es el mismo que el primero, reformateado un poco:

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

Puede agregar métodos extensiones para formar elementos, que a su vez puede desencadenar los eventos:

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

de una sola línea:

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

o, anidada:

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

el uso de este método genérico estática (T es el tipo de destino, de entrada es objeto de emitir, el código es un delegado (o expresión lambda) para ejecutar en caso de éxito:

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

Dale un golpe :) –

+0

Enfoque interesante ... Un poco sofisticado para este ejemplo (ni siquiera sabía que esto es posible) pero definitivamente es bueno saberlo! –

8

Me encanta bueno, limpio código pero en la mayoría de los casos, limpiar & elegante no significa corto e inteligente. La brevedad del código es buena para las competiciones. Cambiar una declaración "si no nula" a un foreach puede parecer mucho mejor, pero es más difícil para todos los demás que trabajan en el proyecto comprender lo que están tratando de lograr. Créame, incluso usted no lo recordará unos meses después: P. ¡Tu código está bien tal como está!

+1

+1 Esta es una respuesta fantástica. –

1

Dado que está utilizando eventos conocidos del .NET framework (a diferencia de un tercero) y del código, parece que solo está utilizando esos métodos para clases específicas (es decir, ListBoxItems y ListBoxes), existen algunas cosas que usted sabe para ser verdad:

  • sender nunca será nula
  • sender siempre será un ListBoxItem o ListBox, respectivamente

Entonces, ¿por qué usar el operador as? ¡Solo echa!

A continuación, el primer fragmento se convierte en

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

Nota esto no es cierto en el caso general (que no haría esto si estuviera manejando todos los eventos PreviewMouseDown en que un controlador para todos los tipos de control), pero para el código de manejo de eventos como este, especialmente en el código UI, puede estar tan seguro como pueda de cualquier cosa, ese remitente no será nulo y el remitente será del tipo esperado.

0

Usando la misma idea que la solución de Utaal, sino como un método de extensión ...

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())); 
}