2013-03-25 95 views
0

在我的代碼後面我將MessageBoxTabControl.ItemsSource設置爲Observable集合。如何訪問TabControl.ContentTemplate中的ListBox?

<TabControl x:Name="MessageBoxTabControl"> 
    <TabControl.ContentTemplate> 
     <DataTemplate> 
      <ListBox x:Name="MessageListBox" /> 
       <!--^I want a reference to this control --> 
     </DataTemplate> 
    </TabControl.ContentTemplate> 
</TabControl> 

假設我有相關的tabcontrol和tabitem,我怎麼能得到我的ListBox的引用?

+0

這可能會幫助:http://msdn.microsoft.com/en-us/library/bb613579.aspx – 2013-03-25 21:28:16

回答

3

你有沒有想過做任何你想要做一些其他的方式?通常情況下,當你有一個DataTemplate時,你可能想要在該模板內的控件上設置的任何屬性應該是靜態的(爲什麼要訪問它們)或依賴於提供的數據,然後應該由DataBinding實現。

您可以使用下面的代碼來獲取ListBox。我仍然覺得重新考慮你的結構而不是使用這個代碼會更好。

的XAML:

<Window x:Class="WpfApplication1.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title="MainWindow" Height="350" Width="525"> 

    <TabControl x:Name="MessageBoxTabControl"> 
     <TabControl.ContentTemplate> 
      <DataTemplate > 
       <ListBox x:Name="MessageListBox" > 
        <ListBoxItem Content="ListBoxItem 1" /> <!-- just for illustration --> 
       </ListBox> 
      </DataTemplate> 
     </TabControl.ContentTemplate> 
     <TabItem Header="Tab 1" /> 
     <TabItem Header="Tab 2" /> 
    </TabControl> 
</Window> 

後面的代碼:

void MainWindow_Loaded(object sender, RoutedEventArgs e) 
{ 
    ListBox lbx = FindVisualChildByName<ListBox>(this.MessageBoxTabControl, "MessageListBox"); 
    if (lbx != null) 
    { 
     // ... what exactly did you want to do ;)? 
    } 
} 

private T FindVisualChildByName<T>(DependencyObject parent, string name) where T : FrameworkElement 
{ 
    T child = default(T); 
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) 
    { 
     var ch = VisualTreeHelper.GetChild(parent, i); 
     child = ch as T; 
     if (child != null && child.Name == name) 
      break; 
     else 
      child = FindVisualChildByName<T>(ch, name); 

     if (child != null) break; 
    } 
    return child; 
} 

還有第二次類似的方式,實際使用的模板,但仍取決於可視化樹去的ContentPresenter (類似於上面的FindVisualChild實現):

ContentPresenter cp = FindVisualChild<ContentPresenter>(this.MessageBoxTabControl); 
ListBox lbx = cp.ContentTemplate.FindName("MessageListBox", cp) as ListBox; 

請注意,由於對可視化樹的依賴性,你總是隻能用這種方法找到選定選項卡的列表框。

0

應該是這樣的:

TabItem relevantTabItem = howeverYouGetThisThing(); 
var grid = System.Windows.Media.VisualTreeHelper.GetChild(relevantTabItem, 0); 
var listBox = (ListBox) System.Windows.Media.VisualTreeHelper.GetChild(grid, 0); 
+0

返回網格實際上 – 0x4f3759df 2013-04-10 19:17:17

+0

對不起,不知道,然後去更深一層 – Akku 2013-04-10 19:22:11

+0

也許你連需要進一步鑽取。畢竟,我不知道TabControl.ContentTemplate是如何構建的,但我想它不應該是一個太複雜的事情,你基本上必須用VisualTreeHelper來遍歷。實際上,我也猜測你在這裏問的是錯誤的問題,而應該問你實際上想要用這個來完成什麼,因爲這很可能可以通過將ListBox的屬性綁定到viewModel屬性來解決,你可以然後輕鬆改變你的模型。 – Akku 2013-04-10 19:29:32

相關問題