1

私のコードビハインドでは、MessageBoxTabControl.ItemsSourceをObservableコレクションに設定しました。

<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への参照を取得するにはどうすればよいですか?

4

2 に答える 2

4

他の方法でやりたいことをやろうと思ったことはありますか?通常、DataTemplateがある場合、そのテンプレート内のコントロールに設定する可能性のあるプロパティは、静的であるか(したがって、それらにアクセスする理由)、提供されたデータに依存する必要があります。これは、DataBindingによって実装される必要があります。

次のコードを使用して、リストボックスを取得できます。このコードを使用するよりも、構造を再考する方がよいと思います。

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

2番目の同様の方法もあります。これは実際にテンプレートを使用しますが、ContentPresenter(上記に類似したFindVisualChild実装)に到達するためにビジュアルツリーに依存します。

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

ビジュアルツリーへのこの依存関係のため、このメソッドでは選択したタブのリストボックスのみが常に表示されることに注意してください。

于 2013-04-10T21:48:27.530 に答える
0

これである必要があります:

TabItem relevantTabItem = howeverYouGetThisThing();
var grid = System.Windows.Media.VisualTreeHelper.GetChild(relevantTabItem, 0);
var listBox = (ListBox) System.Windows.Media.VisualTreeHelper.GetChild(grid, 0);
于 2013-04-10T18:05:50.363 に答える