C# 如何使WPF Listview与Photoshop图层工作相同
正如我们在Photoshop图层窗口(或其他图像编辑工具)中看到的 它有几个特点:C# 如何使WPF Listview与Photoshop图层工作相同,c#,wpf,listview,header,C#,Wpf,Listview,Header,正如我们在Photoshop图层窗口(或其他图像编辑工具)中看到的 它有几个特点: 具有类似文件夹标题的组 (可折叠/可扩展) 未分组的项目(无标题) 通过拖动“手动”排序 对于No 1,我使用expander控件创建了groupped项。 () 在3号情况下,可使用此代码解决手动排序问题。 () 但我不知道如何将未分组的项目列在一起。 当然,未分组的项目可能没有标题 我正在使用ICollectionView和MVVM ICollectionView可以吗?ICollectionView不能。可
ICollectionView可以吗?
ICollectionView
不能。可以这里有一个例子
XAML:
<Window x:Class="WpfWindowDrag.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfWindowDrag="clr-namespace:WpfWindowDrag"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<!--Container style for a groupped item-->
<Style x:Key="RegularContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Header="{Binding Name}" IsExpanded="True">
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Container style for root objects (i.e. non grouped)-->
<Style x:Key="RootContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ItemsPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--This guy lets us select choose proper group for an item.-->
<WpfWindowDrag:CountryStyleSelector x:Key="ContainerStyleSelector"
RegularGroupStyle="{StaticResource RegularContainerStyle}"
RootGroup="{StaticResource RootContainerStyle}" />
</Window.Resources>
<Grid>
<ListView x:Name="lv">
<ListView.GroupStyle>
<GroupStyle ContainerStyleSelector="{StaticResource ContainerStyleSelector}" />
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfWindow
{
public partial class Window1 : Window
{
private const int NumberOfRecords = 20;
private readonly ObservableCollection<Person> _myList;
public Window1()
{
InitializeComponent();
var countries = new[] { "", "US", "China", "India", "Japan", "Ukraine" };
var countriesCount = countries.Length;
_myList = new ObservableCollection<Person>();
var rnd = new Random();
for (int i = 0; i < NumberOfRecords; i++)
{
int countryIndex = rnd.Next(countriesCount);
_myList.Add(new Person() { Name = string.Format("Name {0}", i), Country = countries[countryIndex] });
}
ICollectionView view = CollectionViewSource.GetDefaultView(_myList);
view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
view.SortDescriptions.Add(new SortDescription("Country", ListSortDirection.Ascending));
view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
lv.ItemsSource = view;
}
}
public class Person
{
public string Name { get; set; }
public string Country { get; set; }
}
public class CountryStyleSelector : StyleSelector
{
public Style RegularGroupStyle { get; set; }
public Style RootGroup { get; set; }
public override Style SelectStyle(object item, DependencyObject container)
{
var cvg = item as CollectionViewGroup;
if (cvg == null)
{
return base.SelectStyle(item, container);
}
return string.IsNullOrEmpty(cvg.Name as string) ? RootGroup : RegularGroupStyle;
}
}
}
CS:
<Window x:Class="WpfWindowDrag.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfWindowDrag="clr-namespace:WpfWindowDrag"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<!--Container style for a groupped item-->
<Style x:Key="RegularContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Header="{Binding Name}" IsExpanded="True">
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Container style for root objects (i.e. non grouped)-->
<Style x:Key="RootContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ItemsPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--This guy lets us select choose proper group for an item.-->
<WpfWindowDrag:CountryStyleSelector x:Key="ContainerStyleSelector"
RegularGroupStyle="{StaticResource RegularContainerStyle}"
RootGroup="{StaticResource RootContainerStyle}" />
</Window.Resources>
<Grid>
<ListView x:Name="lv">
<ListView.GroupStyle>
<GroupStyle ContainerStyleSelector="{StaticResource ContainerStyleSelector}" />
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfWindow
{
public partial class Window1 : Window
{
private const int NumberOfRecords = 20;
private readonly ObservableCollection<Person> _myList;
public Window1()
{
InitializeComponent();
var countries = new[] { "", "US", "China", "India", "Japan", "Ukraine" };
var countriesCount = countries.Length;
_myList = new ObservableCollection<Person>();
var rnd = new Random();
for (int i = 0; i < NumberOfRecords; i++)
{
int countryIndex = rnd.Next(countriesCount);
_myList.Add(new Person() { Name = string.Format("Name {0}", i), Country = countries[countryIndex] });
}
ICollectionView view = CollectionViewSource.GetDefaultView(_myList);
view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
view.SortDescriptions.Add(new SortDescription("Country", ListSortDirection.Ascending));
view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
lv.ItemsSource = view;
}
}
public class Person
{
public string Name { get; set; }
public string Country { get; set; }
}
public class CountryStyleSelector : StyleSelector
{
public Style RegularGroupStyle { get; set; }
public Style RootGroup { get; set; }
public override Style SelectStyle(object item, DependencyObject container)
{
var cvg = item as CollectionViewGroup;
if (cvg == null)
{
return base.SelectStyle(item, container);
}
return string.IsNullOrEmpty(cvg.Name as string) ? RootGroup : RegularGroupStyle;
}
}
}
使用系统;
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
命名空间WpfWindow
{
公共部分类Window1:Window
{
私有常量int NumberOfRecords=20;
私有只读可观察收集列表;
公共窗口1()
{
初始化组件();
var国家=新[]{”、“美国”、“中国”、“印度”、“日本”、“乌克兰”};
var countriescont=国家/地区。长度;
_myList=新的ObservableCollection();
var rnd=新随机数();
for(int i=0;i
但请记住,让项目组自动禁用虚拟化并影响性能。如果你需要的东西里面有成千上万的东西,你可能会写你自己的控制或寻找第三方
干杯,安瓦卡。安瓦卡,谢谢你的帮助。我成功地用您的代码显示分组和取消分组的项目。但是,我的问题是,分组项目总是位于底部。在我看来,组本身并没有任何排序描述,以便在未分组的项之间定位。但是如何在列表视图中混合(排序)未分组和分组的项目呢?Youngjae,您可以使用两种排序描述,如下所述:than previous。我认为需要一个全新的方法。我将尝试使用naive stackpanel解决我的问题。