【问题标题】:Cant get a control from a TabControl DataTemplate无法从 TabControl DataTemplate 获取控件
【发布时间】:2011-09-08 02:32:43
【问题描述】:

过去 2 天我一直在谷歌上搜索它,但无法到达任何地方,我无法对 tabcontrol 的数据模板中的任何控件执行任何操作。

首先,代码:

private void Window_Loaded(object sender, RoutedEventArgs e) {
    tabControl1.ItemsSource = new string[] { "TabA", "TabB", "TabC" };
}

private void tabControl1_SelectionChanged(object sender, SelectionChangedEventArgs e) {
    ContentPresenter cp = tabControl1.Template.FindName("PART_SelectedContentHost", tabControl1) as ContentPresenter;

    DataTemplate dt = tabControl1.ContentTemplate;
    Grid g = tabControl1.ContentTemplate.FindName("myGrid", cp) as Grid;
    g.Background = new SolidColorBrush(Colors.Red);
}

xaml

<Window x:Class="tabTest.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" Loaded="Window_Loaded">
<Grid>
    <TabControl IsSynchronizedWithCurrentItem="True" Height="140" Name="tabControl1" Width="230" SelectionChanged="tabControl1_SelectionChanged">
        <TabControl.ContentTemplate>
            <DataTemplate>
                <Grid x:Name="myGrid">                        
                </Grid>
            </DataTemplate>    
        </TabControl.ContentTemplate>            
    </TabControl>
</Grid>

简而言之这一行:

Grid g = tabControl1.ContentTemplate.FindName("myGrid", cp) as Grid;

抛出错误“System.InvalidOperationException” 此操作仅对应用了此模板的元素有效。

我从here得到这个特别的想法

我找到了很多其他的方法,但我似乎无法到达任何地方:(希望有人能指出我正确的方向:)

【问题讨论】:

  • 您是否尝试过遍历可视化树?如果这是您可以接受的方法,我可以发布代码来做到这一点。
  • 不管怎样都行!只要我可以访问 myGrid 我就可以做我需要的事情:)
  • 这实际上是一个棘手的问题,找不到实际应用 ContentTemplate 的站点...

标签: wpf datatemplate tabcontrol


【解决方案1】:

看起来这与运行时实例化 TabControl 的方式有关。似乎第一次引发 SelectionChanged 事件时,ContentTemplate 还没有准备好被访问。如果您再次运行代码并跳过对 ContentTemplate 的第一次访问,您将看到在后续事件中您可以访问此属性而不会引发异常。

通常可以通过调用 Dispatcher.BeginInvoke 来克服这些类型的错误,在这种情况下,它允许运行时在执行代码之前完成对选项卡控件的初始化。

Dispatcher.BeginInvoke(new Action(() =>
    {
        ContentPresenter cp = tabControl1.Template.FindName("PART_SelectedContentHost", tabControl1) as ContentPresenter;
        Grid g = tabControl1.ContentTemplate.FindName("myGrid", cp) as Grid;
        g.Background = new SolidColorBrush(Colors.Red);
    }));

【讨论】:

  • 伊恩,你是个天才!非常感谢!这似乎是有道理的,但我仍然希望它能够工作。我会给出+1,但在mo 没有得到足够的代表:(
猜你喜欢
  • 2012-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-14
  • 1970-01-01
  • 2011-05-13
  • 2013-02-04
  • 1970-01-01
相关资源
最近更新 更多