无法从 TabControl DataTemplate 获取控件

发布于 2024-11-11 17:06:59 字数 1788 浏览 1 评论 0原文

在过去的两天里,我一直在谷歌上搜索这个问题,但无法找到任何结果,我只是无法对选项卡控件的数据模板中的任何控件执行任何操作。

首先,代码:

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” 此操作仅对应用了此模板的元素有效。

这个特殊的想法是我从这里得到

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

I've been googling this for the last 2 days and cant get anywhere, I just cant do anything to any control in a datatemplate of a tabcontrol.

First off, the code:

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>

In short this line:

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

throws an error "System.InvalidOperationException" This operation is valid only on elements that have this template applied.

this particular idea i got from here

I've found loads of other ways of doing this but I cant seem to get anywhere :( hope someone can point me in the right direction :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱你是孤单的心事 2024-11-18 17:06:59

看起来这与运行时实例化 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);
    }));

Looks like it's issue with the way the TabControl is being instantiated by the run time. It appears that the first time the SelectionChanged event is being raised the ContentTemplate is not quite ready to be accessed. If you run your code again and skip over the first access of ContentTemplate you'll see that in subsequent events you can access this property without the exception being thrown.

Often these types of errors can be overcome by calling Dispatcher.BeginInvoke, in this case it allows the run time to finish initializing the tab control before executing your code.

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);
    }));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文