2009-08-14 8 views
0

У меня возникла проблема с поиском элемента, объявленного в DataTemplate, который был применен как объект ContentTemplate to TabItem. Я видел, что в этой проблеме уже есть некоторые решения, но никто из них не работает в моем случае, и я хотел бы понять, почему (очевидно, я ошибаюсь в некотором месте) Вот пример кода:Найти элемент в DataTemplate, примененный к 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> 

Этот код porgrammatically применяется к данному объекту TabItem в следующим образом:

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

После мне нужен доступ к ListView элемент, объявленный в DataTemplate, так что я исполняю коды, найденные вокруг в Интернете, и также на этом сайте. Вот небольшой пример:

/* 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: В этом случае ContentTemplate из ContentPresenter является Null, поэтому сбой выполнения кода. Prolem2: Хорошо, я думаю, может быть мне нужно ориентироваться содержанием 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); 

этого является объектом TabItem. Но все дело в том, что ContentTemplate полностью отличается от указанного выше. Я уверен, что где-то я что-то пропустил, вы можете помочь мне разобраться с проблемой? Спасибо.

ответ

0

Хорошо, здесь мы пришли :) Я решаю проблему, не очень красиво, но кажется, что работает правильно. Как я уже упоминал выше, я использовал метод LoadContent и возвращает мне объект ListView, но, кстати, это не был ListView, который использует пользовательский интерфейс. Поэтому, чтобы решить эту проблему, я добавляю статическое свойство для хранения моего объекта REAL ListView (статический, поскольку у меня есть один DataTemplate, который содержит ListView, общий для нескольких элементов TabItems, поэтому совместно используется ListView) и добавить обработчик событий в мой DataTemplate ->Загружено. Захват этого события, который в моем случае повышает только один за всю жизнь приложения, в RoutedEvent'sOriginalSource Я получил объект REAL ListView, который использует механизм WPF для рендеринга в пользовательском интерфейсе. Надеюсь, что мое решение поможет кому-то. Спасибо всем.

0

Вы не хотите использовать какие-либо свойства шаблона TabItem, так как они используются для создания фактических элементов управления, а не для их хранения. Вы должны иметь возможность искать визуальное дерево для ListView напрямую, а не через DataTemplate.

+0

Несомненно.Я могу решить эту проблему, вызвав момент присвоения ControlTemplate LoadContent(), который в моем конкретном случае возвращает Grid, то есть корень моего DataTemplate. Моя путаница заключалась в том, почему ContentPresenter ничего не содержит? В образцовых кодах, найденных в Интернете, в DataTemplate не было явно выраженной декларации ContentPresenter. В конце концов, я немного изменил свою структуру кода, чтобы облегчить доступ к данным, которые мне нужны другими способами, и быть более простым :), кстати до сих пор я не нашел разрешения такого рода проблем. – Tigran

+0

Одна вещь, которую я заметил, перемещая коды образцов, что они обычно применяют DataTemplate от элемента Parent к элементу. Поэтому я попытался применить свойство ItemTemplate от TabControl (даже если это не так удобно для этого приложения, но только для того, чтобы попытаться понять проблему), но это не сработало. – Tigran

0

Просто, если у вас есть 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 это имя текстового блока
  • Где photoPathColumn - DataGridTemplateColumn.
+1

Это исключение. – Shimmy

Смежные вопросы