2014-09-15 3 views
1

У меня есть приложение WPF в .NET 3.5 SP1, которое использует TabControl.
В этом случае у нас есть TabItems, которые, в свою очередь, имеют свои Styles для определения отображаемых в данный момент элементов.
Скажем, у нас нет в TabItem имени Книги, теперь Книги будет иметь три этапа дисплея:
1. Загрузка результатов,
2. Отображение результатов,
3. не Отображение никаких результатов - то есть ничего не найдено.Как получить VisualChild из ControlTemplate

<TabControl> 
    <TabItem Header="Books"/> 
    <TabItem Header="DVD's"/> 
    ... 
</TavControl> 

Теперь у меня есть 5 TabItems, которые, скажем, представляют собой "DVD,", "Blu-Rays", "компакт-диск", "Книги" и "Комиксы".

<TabItem Header="Books"> 
    <Control> 
     <Control.Resources> 
      <Style TargetType="Control"> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="Control"> 
          <ListView ItemsSource="{Binding Books}"/> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      <Style.Triggers> 
       <!-- Assign different Visuals depending on the current state of the app, i.e. Loading, No results, results found 
       <DataTrigger .../> 
      </Style.Triggers> 
      </Style> 
     </Control.Resources> 
    </Control> 
</TabItem> 

Под TabItem У меня есть TextBlock отображать количество найденных результатов в настоящее время:

<TextBlock> 
    <TextBlock.Text> 
     <MultiBinding StringFormat="Displaying {0} records for your Shop ({1})" Converter="{StaticResource tstMVC}"> 
      <Binding ElementName="Tc" Path="SelectedValue"/> 
      <Binding Path="ShopId" FallbackValue="Liverpool"/> 
     </MultiBinding> 
    </TextBlock.Text> 
</TextBlock> 

конвертер есть для меня, чтобы проверить, какие значения передаются в MultiBinding.
ВОПРОС:
Когда пользователь выбирает вкладку элемента Я хотел бы, чтобы отобразить номер текущего из отображаемых элементов, но я не могу найти ListView в Control, так как это текущее содержимое TabItem.
Я пробовал TabControl.SelectedItem, SelectedValue и до сих пор не могу найти Current ItemsSource.Count.
Заранее спасибо


UPDATE:
Я попробовал оба раствора большое спасибо @Sheridan и @pushpraj!
К сожалению, я не использовал любой из них, вместо этого я использовал ListView внутри TabItem, а затем к нему доступ с помощью этого кода:

<TabControl Name="Tc"> 
    <TabItem><ListView ItemsSource="{Binding Books}"/></TabItem> 
    ... 
</TabControl> 

<TextBlock Text="{Binding ElementName=Tc, Path=SelectedItem.Content.Items.Count}"/> 

Таким образом, содержание моей TextBlock меняется каждый раз, когда пользователь выбирает другую вкладку.
P.S. Тем не менее я бы не сделал этого без оценки обоих ответов.

+1

Я хотел бы предложить, чтобы пойти связывание пути данных. во-вторых, чтобы получить количество элементов, вы можете использовать 'Items.Count' в TabControl. ItemsSource.Count работает только при наличии свойства Count в источнике элементов, например IEnumarable не имеет. – pushpraj

+0

Спасибо за быстрый ответ, но когда я использую 'TabControl.Items.Count', я получаю число TabItems, а не число результатов, возвращаемых из БД. – XAMlMAX

+0

Вы хотите количество книг? возможно, привязка к '{Binding Books.Count}' может помочь вам получить желаемое. – pushpraj

ответ

1

В WPF мы обычно работаем с элементами данных, а не с элементами пользовательского интерфейса. Под этим я подразумеваю, что обычно данные привязываются к данным из нашего кода позади или просматривают модели в элементах пользовательского интерфейса в представлениях, UserControl и Window с.

Таким образом, если у вас есть свойство сбора данных с именем Books в вашем коде или посмотреть модель, вы можете просто обратиться к этой коллекции, чтобы узнать, сколько элементов в ней, а не пытаться найти ее через пользовательский интерфейс управления:

<ListView ItemsSource="{Binding Books}" /> 

Можно даже подвергающие количество элементов в качестве отдельного имущества и привязки данных к нему непосредственно:

public ObservableCollection<Book> Books 
{ 
    get { return books; } 
    set 
    { 
     books = value; 
     NotifyPropertyChanged("Books"); 
     NotifyPropertyChanged("BookCount"); 
    } 
} 

public int BookCount 
{ 
    get { return Books.Count; } 
} 

UPDATE >>>

В ответ на ваш последний комментарий вы можете узнать, как получить доступ к элементам пользовательского интерфейса из ControlTemplate с страницы How to: Find ControlTemplate-Generated Elements на MSDN. Короче говоря, вам нужно получить доступ к элементу, который применяет ControlTemplate (соответствующий TabItem в вашем случае), а затем вы можете использовать FrameworkTemplate.FindName Method для поиска внутренних объявленных элементов. Возьмем такой пример из связанного страницы:

// Finding the grid that is generated by the ControlTemplate of the Button 
Grid gridInTemplate = (Grid)myButton1.Template.FindName("grid", myButton1); 

// Do something to the ControlTemplate-generated grid 
MessageBox.Show("The actual width of the grid in the ControlTemplate: " 
    + gridInTemplate.GetValue(Grid.ActualWidthProperty).ToString()); 
+0

Спасибо, BTW: Я использую MVVM Light в своем приложении, я должен был указать это первым. – XAMlMAX

+1

Здесь не должно быть никакой разницы. – Sheridan

+0

см. Мое обновление :-) – XAMlMAX

1

, если у вас есть отдельные классы коллекций для всех вас лиц, вы можете использовать следующий подход

определить шаблоны данных для классов коллекций

например

<DataTemplate DataType="{x:Type l:BookCollection}"> 
    <ListView ItemsSource="{Binding}" /> 
</DataTemplate> 

xaml

<TabControl x:Name="Tc"> 
    <TabItem Header="Books" 
      Content="{Binding Books}" /> 
    <TabItem Header="DVD's" 
      Content="{Binding DVDs}" /> 
</TabControl> 

или если у вас нет отдельных коллекций используйте DataTemplate следующий

<TabControl x:Name="Tc"> 
    <TabControl.ItemTemplate> 
     <DataTemplate> 
      <ListView ItemsSource="{Binding}" /> 
     </DataTemplate> 
    </TabControl.ItemTemplate> 
    <TabItem Header="Books" 
      Content="{Binding Books}" /> 
    <TabItem Header="DVD's" 
      Content="{Binding DVDs}" /> 
</TabControl> 

то переплет, чтобы получить элементы Выделенной вкладки посчитает будет

<TextBlock Text="{Binding SelectedItem.Content.Count, ElementName=Tc}" /> 
+0

Приятный, теперь я буду оценивать оба ответа и выбирать тот, который сделал лучшее, на мой взгляд, работу. – XAMlMAX

+0

см. Мое обновление :-) – XAMlMAX

+1

Отличная находка @XAMlMAX! ListView или любой элемент ItemsControl также позволят вам подсчитать количество связанных объектов, используя Items property.last, но не в последнюю очередь, счастливое кодирование :) – pushpraj