2013-03-30 3 views
3

Каков наилучший способ отображения нескольких типов данных в потоке данных WPF. Например, для категорий и продуктов:WPF DataGrid отображает несколько типов

 
| Product Name | Description | Price | 
--------------------------------------- 
IT - category 
--------------------------------------- 
    Monitors - category 
--------------------------------------- 
| Monitor 1 | ...   | 100 $ | 
| Monitor 2 | ...   | 99 $ | 
| Monitor 3 | ...   | 120 $ | 
--------------------------------------- 
    HDD - category 
--------------------------------------- 
| Hdd 1  | ...   | 50 $ | 
| Hdd 2  | ...   | 45 $ | 
--------------------------------------- 
Electronics category 
--------------------------------------- 
... 

Я хотел бы, чтобы отобразить на вершине колонны продукта, а также изменить шаблон для категорий. Я знаю, что есть селектор шаблонов ячеек, но есть ли способ указать селектор шаблонов для целой строки? Спасибо.

+1

Похоже, ваши данные иерархическими, в этом случае вы можете захотеть использовать более подходящий контроль, как в 'TreeView'. –

ответ

4

Если вы создаете CollectionViewsource для своих данных, вы можете использовать PropertyGroupDescription в коллекциях GroupDescriptions, чтобы сгруппировать все данные по интересующей вас недвижимости.

Тогда в DataGrid вы можете создать GroupStyle показать TextBlock или что-то, чтобы отделить все группы в DataGrid.

Вот полный рабочий демо, как его немного проще показать, чем объяснить :)

Xaml:

<Window x:Class="WpfApplication20.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="505" Width="525" Name="UI"> 

    <Window.Resources> 

     <!--Create CollectionViewSource and set the property you want to group by--> 
     <CollectionViewSource x:Key="MyItems" Source="{Binding Items, ElementName=UI}"> 
      <CollectionViewSource.GroupDescriptions> 
       <PropertyGroupDescription PropertyName="Category" /> 
      </CollectionViewSource.GroupDescriptions> 
     </CollectionViewSource> 
    </Window.Resources> 

    <Grid> 
     <DataGrid ItemsSource="{Binding Source={StaticResource MyItems}}"> 
      <DataGrid.GroupStyle> 
       <GroupStyle> 
        <GroupStyle.HeaderTemplate> 
         <DataTemplate> 
          <StackPanel> 
           <!--Name property is the GroupName created by the CollectionViewSource--> 
           <TextBlock Text="{Binding Path=Name}" Margin="10,0,0,0" FontSize="18" FontWeight="Bold"/> 
          </StackPanel> 
         </DataTemplate> 
        </GroupStyle.HeaderTemplate> 
       </GroupStyle> 
      </DataGrid.GroupStyle> 
     </DataGrid> 
    </Grid> 
</Window> 

Код:

namespace WpfApplication20 
{ 
    public partial class MainWindow : Window 
    { 
     private ObservableCollection<MyDataObject> _items = new ObservableCollection<MyDataObject>(); 

     public MainWindow() 
     { 
      InitializeComponent(); 
      Items.Add(new MyDataObject { Category = "IT", ProductName = "Stackoverflow", Description = "Group", Price = "Demo" }); 
      Items.Add(new MyDataObject { Category = "Monitors", ProductName = "Stackoverflow", Description = "Group", Price = "Demo" }); 
      Items.Add(new MyDataObject { Category = "Monitors", ProductName = "Stackoverflow", Description = "Group", Price = "Demo" }); 
      Items.Add(new MyDataObject { Category = "Monitors", ProductName = "Stackoverflow", Description = "Group", Price = "Demo" }); 
      Items.Add(new MyDataObject { Category = "HDD", ProductName = "Stackoverflow", Description = "Group", Price = "Demo" }); 
      Items.Add(new MyDataObject { Category = "HDD", ProductName = "Stackoverflow", Description = "Group", Price = "Demo" }); 
     } 

     public ObservableCollection<MyDataObject> Items 
     { 
      get { return _items; } 
      set { _items = value; } 
     } 
    } 

    public class MyDataObject 
    { 
     public string Category { get; set; } 
     public string ProductName { get; set; } 
     public string Description { get; set; } 
     public string Price { get; set; } 
    } 
} 

Результат:

enter image description here

Enhancement

Это может быть хорошей идеей, чтобы переопределить шаблон GroupItem в DataGridContainerStyle, чтобы использовать Expander, таким образом, вы можете расширить свернуть группы.

Пример:

<DataGrid ItemsSource="{Binding Source={StaticResource MyItems}}" CanUserAddRows="False"> 
     <DataGrid.GroupStyle> 
      <GroupStyle> 
       <GroupStyle.ContainerStyle> 
        <Style TargetType="{x:Type GroupItem}"> 
         <Setter Property="Template"> 
          <Setter.Value> 
           <ControlTemplate TargetType="{x:Type GroupItem}"> 
            <Expander Name="expander"> 
             <Expander.Header> 
              <StackPanel > 
               <TextBlock Text="{Binding Name}" FontWeight="Bold"/> 
               <TextBlock Text="{Binding ItemCount, StringFormat={}Items: {0}}" FontSize="9" /> 
              </StackPanel> 
             </Expander.Header> 
             <ItemsPresenter /> 
            </Expander> 
           </ControlTemplate> 
          </Setter.Value> 
         </Setter> 
        </Style> 
       </GroupStyle.ContainerStyle> 
      </GroupStyle> 
     </DataGrid.GroupStyle> 
    </DataGrid> 

Результат:

enter image description here

+0

Спасибо за это, но я не думаю, что группировка решит мою проблему, потому что я хотел бы иметь записи HDD и мониторы как дети IT. Для этого я объединяюсь в свою ViewModel, в той же коллекции два типа объектов: категории и продукты. Моя проблема заключается в том, что я хотел бы иметь возможность применять другой шаблон для этих двух типов записей. Я знаю, что я могу использовать селектор шаблонов ячеек, но мне хотелось бы знать, можно ли использовать селектор шаблонов элементов, чтобы объединить все ячейки для записей категории. – paccic

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