【问题标题】:Find an element in DataTemplate applied to TabItem在应用于 TabItem 的 DataTemplate 中查找元素
【发布时间】:2009-08-14 20:06:05
【问题描述】:

我在尝试查找在 DataTemplate 中声明的元素时遇到问题,该元素之后像 ContentTemplate 一样应用于 TabItem 对象。 我看到关于这个问题已经有一些解决方案,但没有一个真正适用于我的情况,我想了解原因(显然我在某些地方犯了错误) 这是一个示例代码:

<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.ContentTemplate = FindResource("TabItemDataTemplate") as DataTemplate;

在我需要访问在 DataTemplate 中声明的 ListView 元素之后,我执行了在 Internet 上以及在此站点上找到的代码。这是一个简短的例子:

/* 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:好的,我想,可能是我需要直接导航 throw TabItem 内容,所以代码或多或少变成了:

/* 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);

this 是 TabItem 对象。但奇怪的是,this 的 ContentTemplate 与上面分配的完全不同。我确定我在某个地方遗漏了一些东西,你能帮我找出问题所在吗? 谢谢。

【问题讨论】:

    标签: wpf navigation datatemplate


    【解决方案1】:

    您不想使用TabItem 的任何模板属性,因为这些属性用于创建实际控件,而不是存储它们。您应该能够直接在可视化树中搜索ListView,而不是通过DataTemplate

    【讨论】:

    • 当然。我“解决”,可能是这个问题,通过调用 ControlTemplate LoadContent() 的分配时刻,在我的特定情况下返回网格,这是我的 DataTemplate 的根。我的困惑是,为什么 ContentPresenter 不包含任何内容?在互联网上找到的示例代码中,DataTemplate 中没有任何明确的 ContentPresenter 声明。最后,我稍微改变了我的代码结构,以便以其他方式访问我需要的数据,我也更简单:),顺便说一句,直到现在我还没有找到解决这种问题的方法。
    • 我注意到一件事,导航抛出示例代码,他们通常将 DataTemplate 从 Parent 元素应用到 Item。所以我尝试应用 TabControl 的 ItemTemplate 属性(即使它对这个应用程序来说不是那么方便,但只是为了尝试理解问题),但效果不佳。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      简单地说,如果您有一个DataGrid,和一个包含数据模板的TemplateColumn,您可以使用以下代码示例:

      <DataGridTemplateColumn x:Name="photoPathColumn" Header="{x:Static resx:FrmResource.Photo}" Width="Auto">
          <DataGridTemplateColumn.CellEditingTemplate x:Uid="keyelm">
              <DataTemplate x:Name="dodo">
                  <StackPanel Orientation="Horizontal" Height="Auto">
                      <TextBlock x:Name="photo" x:Uid="imageFile" Text="{Binding Path=PhotoPath}"></TextBlock>
                      <Button x:Name="Browse" Content="..." Click="Browse_Click"></Button>
                  </StackPanel>
              </DataTemplate>
          </DataGridTemplateColumn.CellEditingTemplate>
      
      TextBlock tBlock = (TextBlok)photoPathColumn.CellEditingTemplate.FindName(
                             "photo",
                             photoPathColumn.GetCellContent(CustomersDataGrid.CurrentItem));
      
      • photo 是文本块的名称
      • 其中photoPathColumnDataGridTemplateColumn

      【讨论】:

        猜你喜欢
        • 2014-06-05
        • 2012-09-23
        • 2012-12-20
        • 2012-08-03
        • 1970-01-01
        • 1970-01-01
        • 2014-03-01
        相关资源
        最近更新 更多