在适用于TabItem的DataTemplate中查找元素 [英] Find an element in DataTemplate applied to TabItem

查看:93
本文介绍了在适用于TabItem的DataTemplate中查找元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试查找在DataTemplate中声明的元素时遇到问题,该元素像ContentTemplate一样应用于TabItem对象. 我已经看到有关此问题的解决方案,但是在我的情况下没有一个解决方案,我想了解为什么(很明显,我在某些地方犯了错误) 这是示例代码:

I got a problem trying to find an element declared in DataTemplate, that after was applied like a ContentTemplate to TabItem object. I saw that there is already some solutions in regard of this problem, but no one of them actually works in my case, and I would like to understand why (obviously I make mistake in some place) Here is a sample code:

<DataTemplate x:Key="TabItemDataTemplate">             
    <Grid HorizontalAlignment="Stretch" 
        VerticalAlignment="Stretch" Name="templateGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="6.0*"> </RowDefinition>
            <RowDefinition Height="6" ></RowDefinition>
            <RowDefinition Height="6.0*" ></RowDefinition>
            <RowDefinition Height="*" ></RowDefinition>
        </Grid.RowDefinitions>                

        <ListView x:Name="repoView" Grid.Row="0" 
            VerticalAlignment="Stretch"
            ItemsSource="{Binding Source={StaticResource  DataProviderForListView}}">                        
            <GridView>
                <GridViewColumn Header="State"
                    DisplayMemberBinding="{Binding Path=RepositoryItemState}"/>
                <GridViewColumn Header="Working Copy Rev num."
                    DisplayMemberBinding="{Binding Path=WCRevision}"/>
                <GridViewColumn Header="Repository Rev num."
                    DisplayMemberBinding="{Binding Path=RepoRevision}"/>
                <GridViewColumn Header="User"
                    DisplayMemberBinding="{Binding Path=Account}"/>
                <GridViewColumn Header="Item"
                    DisplayMemberBinding="{Binding Path=ItemName}"/>
            </GridView>
        </ListView>

        <GridSplitter x:Name="gridSplitter" Grid.Row="1"
            ResizeDirection="Rows" Background="Gray" 
            Height="4" HorizontalAlignment="Stretch"
            Style="{StaticResource gridSplitterStyle}"/>

        <RichTextBox x:Name="rowView" Grid.Row="2" 
            BorderBrush="Bisque" VerticalAlignment="Stretch"
            IsReadOnly="True" Background="YellowGreen"
            FontFamily="Comic Sans Serif"/>


        <ToggleButton x:Name="rbWorkingCopy"
            Template="{StaticResource ToggleButtonControlTemplate}"
            Grid.Row="3" Width="100" Height="22"
            Content="{StaticResource WorkingCopyTitle}"
            HorizontalAlignment="Left" VerticalAlignment="Bottom"
            Command="repoManager:AppCommands.GetWorkingCopyInfoCommand" />
        <ToggleButton x:Name="rbRepository"
            Template="{StaticResource ToggleButtonControlTemplate}"
            Grid.Row="3"  Width="100" Height="22"
            Content="{StaticResource  RepositoryTitle}"
            HorizontalAlignment="Left"
            VerticalAlignment="Bottom"  Margin="120,0,0,0" 
            Command="repoManager:AppCommands.GetRepoInfoCommand" />
        <ProgressBar x:Name="checkRepositoryProgress" Grid.Row="3"
            Width="220" Height="22" HorizontalAlignment="Right"  
            VerticalAlignment="Bottom" Margin="250,0,10,0"
            IsIndeterminate="True"
            IsEnabled="{Binding repoManager:ExecutingCommand}"  />
    </Grid>
</DataTemplate>

此代码通过以下方式以语法方式应用于给定的TabItem对象:

This code is porgrammatically applied to the given TabItem object in following way :

this.ContentTemplate = FindResource("TabItemDataTemplate") as DataTemplate;

在我需要访问DataTemplate中声明的ListView元素之后,我将在Internet以及该站点上执行发现的代码.这是一个简短的示例:

After I need access to the ListView element declared in DataTemplate, so I execute the codes found around in internet, and also on this site. Here is a short example:

/* Getting the ContentPresenter of myListBoxItem*/          
ContentPresenter myContentPresenter =
    FindVisualChild<ContentPresenter>(this);

// this.GetVisualChild(0)
/* Finding textBlock from the DataTemplate that is set on that ContentPresenter*/
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;

ListView repoListView = (ListView)myDataTemplate.FindName("repoView", 
    myContentPresenter);

问题1:在这种情况下,ContentPresenter的 ContentTemplate 为Null,因此代码执行崩溃. Prolem2:好的,我想可能是我需要直接导航抛出TabItem的内容,所以代码变得或多或少:

Problem1: In this case ContentTemplate of ContentPresenter is Null, so code execution crashes. Prolem2: Ok, I think, may be I need to navigate throw TabItem content directly, so the code becomes, more or less:

/* Getting the ContentPresenter of myListBoxItem*/          
ContentPresenter myContentPresenter =
    FindVisualChild<ContentPresenter>(this);

// this.GetVisualChild(0)
/* Finding textBlock from the DataTemplate that is set on that ContentPresenter*/
DataTemplate myDataTemplate = this.ContentTemplate;

ListView repoListView = (ListView)myDataTemplate.FindName("repoView", 
    myContentPresenter);

是TabItem对象.但有趣的是,的ContentTemplate与上面分配的内容模板完全不同.我确定我在某处错过了什么,您能帮我解决问题吗? 谢谢.

this is TabItem object. But the strage things, that the ContentTemplate of this is completely different from that one assigned above. I'm sure that I missed something somewhere, can you help me to figure out the problem ? Thank you.

推荐答案

好的,我们来了:) 我以不太理想的方式解决了问题,但似乎可以正常工作. 如前所述,我使用了LoadContent方法,它返回了ListView对象,但顺便说一句,它不是UI实际使用的ListView.因此,为解决该问题,我添加了静态属性来保存我的REAL ListView对象(静态,因为我有一个包含跨多个TabItem共享的ListView的DataTemplate,所以也共享了ListView),并将事件处理程序添加到我的DataTemplate-> Loaded .捕获此事件,以我为例,它仅在应用程序的生命周期内引发事件,因此在 RoutedEvent的 OriginalSource 中,我得到了WPF引擎用于在UI上呈现的REAL ListView对象. 希望我的解决方案能对某人有所帮助. 谢谢大家.

Ok, here we come :) I resolve the problem, in not very nice way, but it seems that works correctly. As I mentioned above I used LoadContent method and it returns me the ListView object, but by the way it wasn't the ListView that UI actually uses. So to resolve that problem I add static property to hold my REAL ListView object (static as I have single DataTemplate that contains ListView shared across multiple TabItems, so the ListView shared too) and add event handler to my DataTemplate -> Loaded. Catching this event, that in my case raises only ones in lifetime of application, in RoutedEvent's OriginalSource I got the REAL ListView object that WPF engine uses for rendering on UI. Hope my solution will help someone. Thank you all.

这篇关于在适用于TabItem的DataTemplate中查找元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆