2016-04-25 26 views
2

我想通過使用XAML代碼來分組和顯示ObservableCollection的項目。它使用一個簡單的CollectionViewSource和一個ListBox [1]很好地工作。與TabControl使用CollectionViewSource

其實,我寧願在tabcontrol中顯示組的內容。谷歌使我對下面的文章social.msdn至極提出了一個解決辦法,以顯示作爲組一個TabControl使用後面的代碼:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/e073f275-0826-4fca-b9da-e310ccf1713e/wpf-grouping?forum=wpf

然而,當我使用MVVM並且只能依靠XAML中,我不能讓它工作。實際上,CollectionViewSource填充組(TabControl顯示正確的tabItemHeaders),但單擊任何這些TabItems都會凍結應用程序。以下是我已經試過:

<StackPanel x:Key="ModulSelectInputParameterView"> 
    <StackPanel.Resources> 
     <CollectionViewSource x:Key="cvs" x:Name="collectionViewSource" Source="{Binding ReferencedLmtItem.ModulInputParameterCollection }"> 
      <CollectionViewSource.GroupDescriptions> 
       <PropertyGroupDescription PropertyName="Category"/> 
      </CollectionViewSource.GroupDescriptions> 
     </CollectionViewSource> 
    </StackPanel.Resources> 

    <Grid > 
     <TabControl ItemsSource="{Binding Source={StaticResource cvs}, Path=Groups, Mode=OneWay}" DataContext="{Binding Source={StaticResource cvs}, Mode=OneWay}"> 
      <!-- First Level --> 
      <TabControl.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Name}"/> 
       </DataTemplate> 
      </TabControl.ItemTemplate> 
      <TabControl.ContentTemplate> 
       <DataTemplate> 
        <ListBox ItemsSource="{Binding Items}"> 
         Second Level 
         <ListBox.ItemTemplate> 
          <DataTemplate> 
           <Expander Header="{Binding Name}"> 
            <ListBox ItemsSource="{Binding Items}"> 
             The Item of the Collection 
             <ListBox.ItemTemplate> 
              <DataTemplate> 
               <StackPanel Orientation="Horizontal"> 
                <TextBlock Text="{Binding Key}"/> 
                <TextBlock Text=" - "/> 
                <TextBlock Text="{Binding Value.Comment}"/> 
               </StackPanel> 
              </DataTemplate> 
             </ListBox.ItemTemplate> 
            </ListBox> 
           </Expander> 
          </DataTemplate> 
         </ListBox.ItemTemplate> 
        </ListBox> 
       </DataTemplate> 
      </TabControl.ContentTemplate> 
     </TabControl> 
    </Grid> 

</StackPanel> 

[1]:XAML的這種和平做工作不如預期,但使用wrappanel顯示組內容:

<StackPanel x:Key="ModulSelectInputParameterView"> 
    <StackPanel.Resources> 
     <CollectionViewSource x:Key="cvs" x:Name="collectionViewSource" Source="{Binding ReferencedLmtItem.ModulInputParameterCollection }"> 
      <CollectionViewSource.GroupDescriptions> 
       <PropertyGroupDescription PropertyName="Category"/> 
      </CollectionViewSource.GroupDescriptions> 
     </CollectionViewSource> 
    </StackPanel.Resources> 

    <ListBox ItemsSource="{Binding Source={StaticResource cvs}}" VerticalContentAlignment="Top" ItemContainerStyle="{StaticResource ModulSelectInputParameterListBoxItemContainerStyle}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 
     <ListBox.GroupStyle> 
      <GroupStyle> 
       <GroupStyle.HeaderTemplate> 
        <DataTemplate> 
         <Border BorderBrush="DarkGray" BorderThickness="2" Margin="2"> 
          <TextBlock FontWeight="Bold" FontSize="14" Text="{Binding Path=Name}" HorizontalAlignment="Center" MinWidth="100"/> 
         </Border> 
        </DataTemplate> 
       </GroupStyle.HeaderTemplate> 
       <GroupStyle.Panel> 
        <ItemsPanelTemplate> 
         <WrapPanel Orientation="Horizontal" Margin="2"/> 
        </ItemsPanelTemplate> 
       </GroupStyle.Panel> 
       <GroupStyle.ContainerStyle> 
        <Style TargetType="{x:Type GroupItem}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> 
         <Setter Property="Control.Template"> 
          <Setter.Value> 
           <ControlTemplate TargetType="{x:Type GroupItem}"> 
            <Border BorderThickness="2" BorderBrush="DarkGray"> 
             <StackPanel> 
              <ContentPresenter Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" /> 
              <ItemsPresenter Margin="2,0,2,2" /> 
             </StackPanel> 
            </Border> 
           </ControlTemplate> 
          </Setter.Value> 
         </Setter> 
        </Style> 
       </GroupStyle.ContainerStyle> 
      </GroupStyle> 

     </ListBox.GroupStyle> 
     <ListBox.ItemsPanel> 
      <ItemsPanelTemplate> 
       <WrapPanel IsItemsHost="True" Orientation="Vertical" VerticalAlignment="Top"/> 
      </ItemsPanelTemplate> 
     </ListBox.ItemsPanel> 

    </ListBox> 
</StackPanel> 

回答

1

我覺得有什麼不對您的綁定你的代碼應該工作。 要獲得兩個ListBox相同的項目嘗試將第二個列表框的ItemsSource綁定到的ItemsSource第一ListBox中是這樣的:

<ListBox ItemsSource="{Binding Items}" Name="ListBox"> 

            <ListBox.ItemTemplate> 
             <DataTemplate> 
              <Expander Header="{Binding Key}"> 
               <ListBox ItemsSource="{Binding ItemsSource, ElementName=ListBox}"> 

                <ListBox.ItemTemplate> 
                 <DataTemplate> 
                  <StackPanel Orientation="Horizontal"> 
                   <TextBlock Text="{Binding Key}"/> 
                   <TextBlock Text=" - "/> 
                   <TextBlock Text="{Binding Value}"/> 
                  </StackPanel> 
                 </DataTemplate> 
                </ListBox.ItemTemplate> 
               </ListBox> 
              </Expander> 
             </DataTemplate> 
            </ListBox.ItemTemplate> 
           </ListBox> 
+0

不幸的是,這並沒有解決問題。但是我收到以下錯誤消息,可能是由於此錯誤的原因可能有助於解決此問題: 「構建事件路由時發現的樹中的潛在循環。」 – Bechi

+0

認爲你應該從你的TabControl中刪除'datacontext' – Johannes

+1

確實,錯誤消息給出了提示: 它不是(不必要的)DataContext。這是一個關於DataTemplates的問題,它使用數據觸發器進行更新,這會導致樹中的上述循環。 Joh。的解決方案似乎工作正常,我會在一個單獨的答案中給出關於錯誤的簡要更新。 – Bechi

2

感謝荷蘭Joh誰用適當的數據綁定幫助。然而,原因是完全不同的,下面給出了一個快速和骯髒的解決方案[1]:

基本上,我錯過了上面提到的選項卡控件嵌套在我的主窗口中的外部選項卡控件。我並不十分確定以下描述是否完全正確[1],但在我看來,原因如下:

  • 外部TabControl使用樣式顯示其內容。此內容適用於ViewModel,該ViewModel包含上述可觀察集合,而該集合反過來應該是CollectionViewSource的ItemsSource,它將內部tabControl與組一起提供。
  • 由於我僅在外部TabControl.Resources中定義了此樣式,並且錯過了爲內部選項卡Control定義單獨樣式的問題,所以內部tabcontrol繼承外部樣式並嘗試使用相同內容顯示其數據。
  • 此內容是另一個內部tabControl,它調用另一個內部tabControl等。

[1]定義的inenr tabControl.Resources空樣式解決了這個問題:

<TabControl.Resources> 
       <Style TargetType="TabItem"> 

       </Style> 
      </TabControl.Resources> 

我會很高興,如果有人能證實這種想法,或者提供一些鏈接衆所周知的問題與共享嵌套控件中的樣式。