使用模板将数据分组到项目控件中
Grouping data into itemscontrol(s) with template
根据一些示例和博客,我做了一个小项目来测试 xaml 中某些元素的分组。代码是:
<Window.Resources>
<XmlDataProvider x:Key="data">
<x:XData>
<Devices xmlns="">
<Terminal name="Gasoline" Code="00001001" />
<Terminal name="cherosene" Code="00001002" />
<Terminal name="Oil" Code="00001002" />
<Terminal name="Wather" Code="00001003" />
<Terminal name="cherosene" Code="00001003" />
<Terminal name="Wather" Code="00001004" />
<Terminal name="cherosene" Code="00001004" />
<Terminal name="Oil" Code="00001004" />
<Terminal name="cherosene" Code="00001004" />
<Terminal name="alcohol" Code="00001005" />
</Devices>
</x:XData>
</XmlDataProvider>
<CollectionViewSource x:Key="TerminalByCodes" Source="{Binding Source={StaticResource data}, XPath=Devices/Terminal}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="@Code" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<DockPanel>
<ScrollViewer DockPanel.Dock="Bottom" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Source={StaticResource TerminalByCodes}}" >
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<GroupBox Header="{Binding Name}">
<ItemsPresenter/>
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=@name}" Background="#FFDBA8A8" Margin="0,0,10,0" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
</Grid>
这段代码有这样的输出:
如你所见,数据都写在了xaml中。但是,正如你想象的那样,这不是我必须工作的方式。我如何更新我的代码以使其适用于 "code-generated-data"?如果它是用 mvvm 绑定制作的呢?
拯救皮耶罗!
您可以在视图模型中实例化 CollectionViewsSource class :
CollectionViewSource viewSource = new CollectionViewSource();
并向其提供一些数据:
private List<Terminal> terminals = new List<Terminal>
{
new Terminal{ Code="00001001", Name= "Gasoline" },
new Terminal{ Code="00001001", Name= "cherosene"},
new Terminal{ Code="00001001", Name= "Oil"},
new Terminal{ Code="00001003", Name= "Gasoline" },
new Terminal{ Code="00001003", Name= "cherosene"},
new Terminal{ Code="00001003", Name= "Oil"},
};
terminalsViewSource.Source = terminals;
在视图模型 class 中创建一个 属性 以便数据绑定可以工作:
public Object TerminalsView
{
get { return terminalsViewSource.View; }
}
在后面的代码中,您可以创建 ViewModel :
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
绑定到 .xaml :
<DataGrid x:Name="datagridTerminals" ItemsSource="{Binding TerminalsView}" AutoGenerateColumns="True" >
此外,您可以在 Viewmodel 中添加 Filter、IsSorted、IsGrouped 属性,以便可以过滤(例如按名称)、分组(或不分组)和排序数据。
例如:
<TextBox x:Name="textboxFilter" Text="{Binding Filter}" />
属性 在 ViewModel 中:
public String Filter
{
get { return filter; }
set
{
filter = value;
terminalsViewSource.View.Refresh();
}
}
此处代码示例中的所有内容:
极限竞速!
根据一些示例和博客,我做了一个小项目来测试 xaml 中某些元素的分组。代码是:
<Window.Resources>
<XmlDataProvider x:Key="data">
<x:XData>
<Devices xmlns="">
<Terminal name="Gasoline" Code="00001001" />
<Terminal name="cherosene" Code="00001002" />
<Terminal name="Oil" Code="00001002" />
<Terminal name="Wather" Code="00001003" />
<Terminal name="cherosene" Code="00001003" />
<Terminal name="Wather" Code="00001004" />
<Terminal name="cherosene" Code="00001004" />
<Terminal name="Oil" Code="00001004" />
<Terminal name="cherosene" Code="00001004" />
<Terminal name="alcohol" Code="00001005" />
</Devices>
</x:XData>
</XmlDataProvider>
<CollectionViewSource x:Key="TerminalByCodes" Source="{Binding Source={StaticResource data}, XPath=Devices/Terminal}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="@Code" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<DockPanel>
<ScrollViewer DockPanel.Dock="Bottom" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Source={StaticResource TerminalByCodes}}" >
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<GroupBox Header="{Binding Name}">
<ItemsPresenter/>
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=@name}" Background="#FFDBA8A8" Margin="0,0,10,0" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
</Grid>
这段代码有这样的输出:
如你所见,数据都写在了xaml中。但是,正如你想象的那样,这不是我必须工作的方式。我如何更新我的代码以使其适用于 "code-generated-data"?如果它是用 mvvm 绑定制作的呢?
拯救皮耶罗!
您可以在视图模型中实例化 CollectionViewsSource class :
CollectionViewSource viewSource = new CollectionViewSource();
并向其提供一些数据:
private List<Terminal> terminals = new List<Terminal>
{
new Terminal{ Code="00001001", Name= "Gasoline" },
new Terminal{ Code="00001001", Name= "cherosene"},
new Terminal{ Code="00001001", Name= "Oil"},
new Terminal{ Code="00001003", Name= "Gasoline" },
new Terminal{ Code="00001003", Name= "cherosene"},
new Terminal{ Code="00001003", Name= "Oil"},
};
terminalsViewSource.Source = terminals;
在视图模型 class 中创建一个 属性 以便数据绑定可以工作:
public Object TerminalsView
{
get { return terminalsViewSource.View; }
}
在后面的代码中,您可以创建 ViewModel :
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
绑定到 .xaml :
<DataGrid x:Name="datagridTerminals" ItemsSource="{Binding TerminalsView}" AutoGenerateColumns="True" >
此外,您可以在 Viewmodel 中添加 Filter、IsSorted、IsGrouped 属性,以便可以过滤(例如按名称)、分组(或不分组)和排序数据。
例如:
<TextBox x:Name="textboxFilter" Text="{Binding Filter}" />
属性 在 ViewModel 中:
public String Filter
{
get { return filter; }
set
{
filter = value;
terminalsViewSource.View.Refresh();
}
}
此处代码示例中的所有内容:
极限竞速!