2009-06-17 22 views
5

我承認,它是一種微小的,但我正在尋找更好的方法來做下面的代碼塊。他們應該是自我解釋...C#EventHandler美麗的代碼(如何?)

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

再醜之一:

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

是啊,我知道,它不是瀕死緊急。但我不喜歡(如果!= null)。任何神奇的想法,縮短甚至更多:-)

順便說一句,我發現關於類似的話題了一些不錯的信息:Loops on Null Items 尼斯讀...

回答

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

也許我只是被迂腐但爲什麼你需要如果您在其主機容器代碼中使用該事件,則可以投送發件人。

無論誰對列表進行了更改,是否可以給列表框添加一個名稱並使用它。

<ListBox x:Name="listbox1" /> 

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

或者你甚至可以實現一些使用綁定,沒有代碼背後。

+0

這個問題的唯一目的就是吹毛求疵:-)但還不錯的主意,將在進一步考慮節目。說實話,我認爲我接近良好的做法,但你永遠不會知道...... – 2009-06-17 23:57:16

0

這應該是一樣的第一個,重新格式化一點點:

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

您可以添加擴展方法來形成元素,這樣就可以觸發事件:

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

一襯墊

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

,或者嵌套:

private void listBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    As<ListBoxItem>(sender, (listBoxItem) => { 
     As<ClickObject>(listBoxItem.DataContext, 
      (clickObject) => clickObject.SingleClick()); 
    }; 
} 
使用這種靜態的通用方法

(T是目標類型,輸入爲對象投射,碼是一個代表(或λ表達),以對成功執行:

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

打我吧:) – 2009-06-18 00:34:50

+0

有趣的方法...這個例子有點複雜(甚至不知道這是可能)但很高興知道! – 2009-06-18 00:39:09

8

我愛好,清潔代碼,但在大多數情況下,優雅並不意味着簡潔和智能。代碼簡潔有利於競爭。將「if not null」語句更改爲foreach可能看起來更酷,但在項目中工作的每個人都很難理解您要完成的任務。相信我,即使你幾個月後不會記得它:P。你的代碼很好,因爲它是!

+1

+1這是一個夢幻般的答案。 – 2009-06-18 00:44:16

1

由於您使用的.NET框架(而不是第三方)的已知事件,並從代碼看起來像你只使用這些方法的特定類(即ListBoxItems和ListBoxes),有你知道的幾件事情是真實的:

  • sender永遠不會爲空
  • sender永遠是一個ListBoxItem,或列表框,分別爲

那麼爲什麼要使用as運算符?只需投!

然後第一個片段成爲

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

注意,這不是在一般情況下,真正的(你不會做,如果你正在處理中的一個處理所有PreviewMouseDown事件對所有的控件類型)但對於像這樣的事件處理代碼,尤其是在UI代碼中,您可以確定任何事情,發件人不會爲空,並且發件人的類型與您期望的類型相同。

0

使用相同的思路Utaal的解決方案,但作爲一個擴展方法...

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