2010-11-30 111 views
1

我有一個ListBox數據綁定到我的PersonCollection類的集合。接下來,我爲Person類型的對象定義了一個數據模板,其中包含一個DockPanel,其中包含一個人姓名的TextBlock和一個Button以將該人從列表中刪除。它們看起來非常漂亮。遍歷WPF元素樹的問題

我面臨的問題是,當我單擊數據模板中定義的按鈕時,我無法到達列表框中的選定項目(並將其刪除)。下面是該按鈕的處理程序:

private void RemovePersonButton_Click(object sender, RoutedEventArgs e) 
{ 
    Button clickedButton = (Button)e.Source; 
    DockPanel buttonPanel = (DockPanel)clickedButton.Parent; 
    Control control = (Control)button.Parent; 
} 

最後創建的對象controlnull,即我不能再進步了元素樹,所以我不能觸及名單及其SelectedItem。這裏需要注意的重要一點是,不能簡單地通過調用它來從列表中獲取選定的項目,因爲我在窗口中有多個列表,並且所有這些列表實現相同的數據模板,即共享相同的事件處理程序刪除按鈕。

我將不勝感激所有我能得到的幫助。謝謝。

回答

3

如果我理解正確的問題,我想你就可以從按鈕的DataContext的得到人

private void RemovePersonButton_Click(object sender, RoutedEventArgs e) 
{ 
    Button clickedButton = (Button)e.Source; 
    Person selectedItem = clickedButton.DataContext as Person; 
    if (selectedItem != null) 
    { 
     PersonCollection.Remove(selectedItem); 
    } 
} 

另一種方法是找到的ListBox中的VisualTree

private void RemovePersonButton_Click(object sender, RoutedEventArgs e) 
{ 
    Button clickedButton = (Button)e.Source; 
    ListBox listBoxParent = GetVisualParent<ListBox>(clickedButton); 
    Person selectedItem = listBoxParent.SelectedItem as Person; 
    //... 
} 

public T GetVisualParent<T>(object childObject) where T : Visual 
{ 
    DependencyObject child = childObject as DependencyObject; 
    while ((child != null) && !(child is T)) 
    { 
     child = VisualTreeHelper.GetParent(child); 
    } 
    return child as T; 
} 
+0

正確!很好。我不知道'DataContext`屬性。值得一提的是,我可以通過調用`VisualTreeHelper.GetParent(DependencyObject引用)`方法來查找元素樹,但這是一個更好的解決方案!謝謝。 – Boris 2010-11-30 23:18:21

+0

我更喜歡第一個解決方案。感謝發佈! – Boris 2010-11-30 23:20:35

0

你可能會嘗試使用VisualTreeHelper.GetParent來行走視覺樹,而不是依靠邏輯父項。這就是說,你可能會考慮是否可以將Person包裝在PersonItem類中,並附加上下文信息,以便PersonItem知道如何從列表中刪除Person。我有時會使用這種模式,並且我編寫了一個EncapsulatingCollection類,該類根據監視的ObservableCollection中的更改自動實例化包裝器對象。