2009-06-17 26 views
5

Tôi thừa nhận, nó là loại nhỏ, nhưng tôi đang tìm cách tốt hơn để làm các khối mã sau đây. Họ nên tự giải thích ...C# EventHandler Mã đẹp (Làm thế nào?)

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

Một xấu xí một:

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

Vâng, tôi biết, nó không cận kề cái chết khẩn cấp. Nhưng tôi KHÔNG thích (nếu! = Null). Bất cứ ý tưởng kỳ diệu để rút ngắn nó thậm chí nhiều hơn :-)

Btw, tôi thấy một số thông tin tốt đẹp về một chủ đề tương tự: Loops on Null Items Rất vui được đọc ...

Trả lời

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

Có vẻ đẹp hơn nhiều sau đó mã của tôi :-) –

0

Có lẽ tôi chỉ là pedantic nhưng tại sao bạn cần để truyền người gửi nếu bạn đang sử dụng sự kiện trong mã vùng chứa máy chủ lưu trữ của nó.

Bất kể ai đã thực hiện thay đổi đối với danh sách, bạn có thể chỉ đặt tên hộp danh sách của mình và sử dụng tên đó không.

<ListBox x:Name="listbox1" /> 

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

Hoặc bạn thậm chí có thể đạt được một số điều này bằng cách ràng buộc không có mã phía sau.

+0

Mục đích duy nhất của câu hỏi này là tóc chẻ :-) Nhưng cũng ý tưởng tốt, sẽ được xem xét trong hơn nữa lập trình. Thành thật mà nói, tôi nghĩ rằng tôi gần với thực hành tốt, nhưng bạn sẽ không bao giờ biết ... –

0

này được coi là tương tự như một trong những đầu tiên, định dạng lại một chút:

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

Bạn có thể thêm các phương pháp mở rộng Mẫu số yếu tố, sau đó có thể kích hoạt các sự kiện:

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

hay, lồng nhau:

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

sử dụng phương pháp chung tĩnh này (T là loại đích, đầu vào là đối tượng để đúc, mã là một đại biểu (hoặc biểu thức lambda) để thực hiện thành công:

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

Đánh bại tôi với nó :) –

+0

Cách tiếp cận thú vị ... Một chút để tinh vi cho ví dụ này (thậm chí không biết điều này là có thể) nhưng chắc chắn là tốt đẹp để biết !! –

8

Tôi yêu tốt, sạch sẽ nhưng trong hầu hết các trường hợp, làm sạch & thanh lịch không có nghĩa là ngắn và thông minh. Mã ngắn gọn là tốt cho các cuộc thi. Thay đổi một tuyên bố "nếu không null" cho một foreach có thể có vẻ mát mẻ hơn nhưng nó khó khăn hơn cho tất cả những người khác làm việc trong dự án để hiểu những gì bạn đang cố gắng để thực hiện. Tin tôi đi, thậm chí bạn sẽ không nhớ nó vài tháng sau: P. Mã của bạn chỉ là tốt như nó được!

+1

+1 Đây là một câu trả lời tuyệt vời. –

1

Vì bạn đang sử dụng các sự kiện đã biết từ khuôn khổ .NET (như trái ngược với bên thứ ba) và từ mã có vẻ như bạn chỉ sử dụng các phương thức đó cho các lớp cụ thể (ví dụ: ListBoxItems và ListBoxes) một vài điều bạn biết đến mức khó tin:

  • sender sẽ không bao giờ được null
  • sender sẽ luôn là một ListBoxItem, hoặc ListBox, tương ứng

Vậy tại sao sử dụng toán tử as? Chỉ cần cast!

Sau đó đoạn đầu tiên trở thành

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

Chú giải này là không đúng trong trường hợp chung (bạn sẽ không làm được điều này nếu bạn đang xử lý tất cả các sự kiện PreviewMouseDown trong đó một handler cho tất cả các loại Control), nhưng đối với mã xử lý sự kiện như thế này, đặc biệt là trong mã giao diện người dùng, bạn có thể chắc chắn như bất kỳ thứ gì, người gửi đó sẽ không bị rỗng và người gửi sẽ thuộc loại bạn mong đợi.

0

Sử dụng ý tưởng tương tự như giải pháp Utaal, nhưng như một phương pháp khuyến nông ...

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())); 
} 
Các vấn đề liên quan