在ListView
中显示组标题,而不是按排序键。
您好,我正在为Windows 10移动版开发UWP应用程序。
我有一个ListView
,其中包含SQLite数据库中的项目。每个项目都属于一个类别,ListView
按类别分组。在显示中,组的标题是类别的名称,并且这些类别按字母顺序排序。
XAML代码的主要元素是:
<ListView x:Name="listBoxobj"
ItemsSource="{Binding Source={StaticResource cvsource}}"
BorderBrush="#FF141EE4"
Margin="0,0,0,0"
HorizontalAlignment="Stretch"
SelectionMode="None"
IsItemClickEnabled="True"
RightTapped="listBoxobj_RightTapped"
SelectedItem="{Binding Name}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="NameTxt" Grid.Column="0" Margin="0,0,0,0" TextWrapping="Wrap" Text="{Binding NomArt}" FontSize="20" Foreground="White"/>
<TextBlock x:Name="QteArtTxt" Grid.Column="0" Margin="20,0,0,0" TextWrapping="Wrap" Text="{Binding QuantArt}" FontSize="20" Foreground="DarkGray" FontStyle="Italic"/>
<TextBlock x:Name="UniteMesureTxt" Grid.Column="0" Margin="10,0,0,0" TextWrapping="Wrap" Text="{Binding UnitArt}" FontSize="20" Foreground="DarkGray" FontStyle="Italic"/>
</StackPanel>
<Button x:Name="btnPanier" Grid.Column="1" Height="35" Width="35" Tag="{Binding}" Click="btnPanier_Click">
<Button.Background>
<ImageBrush ImageSource="/Assets/Images/icone_caddie_40x40.png" Stretch="UniformToFill">
</ImageBrush>
</Button.Background>
</Button>
<TextBlock x:Name="NoteTxt" Grid.Row="2" Margin="0,20,0,0" TextWrapping="Wrap" Text="{Binding NoteArt}" FontSize="16" Foreground="DarkGray" FontStyle="Italic"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Key}" Foreground="CadetBlue" FontSize="18" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<MenuFlyout x:Name="MenuFlyoutContext" x:Key="FlyoutBaseKey">
<MenuFlyoutItem x:Name="MFSubMenu1" x:Uid="MenuFlyoutModif" Click="MFSubMenu1_Click"/>
<MenuFlyoutItem x:Name="MFSubMenu2" x:Uid="MenuFlyoutDelete" Click="MFSubMenu2_Click"/>
</MenuFlyout>
</ListView.Resources>
<FlyoutBase.AttachedFlyout>
<StaticResource ResourceKey="FlyoutBaseKey"/>
</FlyoutBase.AttachedFlyout>
</ListView>
下面是显示ListView的代码:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();
currentListeAchat = e.Parameter as string;
textBlock.Text = resourceLoader.GetString("PanierTitre") + " " + currentListeAchat;
//
Achats = new ObservableCollection<Achat>();
AchatsIn = new ObservableCollection<Achat>();
//
DB_PanierList = dbpaniers.GetAllPaniers();
var query = DB_PanierList.Where(x => x.NomListe == currentListeAchat & x.InOut == "Out");
//
foreach (var item in query)
{
string nomart = item.Name;
string quantart = item.QteArt;
string noteart = item.Note;
string catart = item.NomCat;
int catorder = item.OrdreCat;
string unitart = item.UniteMesure;
string inout = item.InOut;
Achats.Add(new Achat()
{
NomArt = nomart,
QuantArt = quantart,
NoteArt = noteart,
CatArt = catart,
CatOrder = catorder,
UnitArt = unitart,
InOut = inout
});
}
//
_groupingCollection = new ObservableGroupingCollection<string, Achat>(Achats);
_groupingCollection.ArrangeItems(new CatSorter(), (x => x.CatOrder.ToString()));
GroupedAchats = _groupingCollection.Items;
cvsource.Source = GroupedAchats;
//
//
var queryin = DB_PanierList.Where(x => x.NomListe == currentListeAchat & x.InOut == "In");
//
foreach (var item in queryin)
{
string nomart = item.Name;
string quantart = item.QteArt;
string noteart = item.Note;
string catart = item.NomCat;
int catorder = item.OrdreCat;
string unitart = item.UniteMesure;
string inout = item.InOut;
AchatsIn.Add(new Achat()
{
NomArt = nomart,
QuantArt = quantart,
NoteArt = noteart,
CatArt = catart,
CatOrder = catorder,
UnitArt = unitart,
InOut = inout
});
}
//
_groupingCollectionIn = new ObservableGroupingCollection<string, Achat>(AchatsIn);
_groupingCollectionIn.ArrangeItems(new CatSorter(), (x => x.CatArt));
GroupedAchatsIn = _groupingCollectionIn.Items;
cvsourceIn.Source = GroupedAchatsIn;
//
// Register for hardware and software back request from the system
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested += OnBackRequested;
}
以及类ObservableGroupingCollection:
public class ObservableGroupingCollection<K, T> where K : IComparable
{
public ObservableGroupingCollection(ObservableCollection<T> collection)
{
_rootCollection = collection;
_rootCollection.CollectionChanged += _rootCollection_CollectionChanged;
}
ObservableCollection<T> _rootCollection;
private void _rootCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
HandleCollectionChanged(e);
}
ObservableCollection<Grouping<K, T>> _items;
public ObservableCollection<Grouping<K, T>> Items
{
get { return _items; }
}
IComparer<T> _sortOrder;
Func<T, K> _groupFunction;
public void ArrangeItems(IComparer<T> sortorder, Func<T, K> group)
{
_sortOrder = sortorder;
_groupFunction = group;
var temp = _rootCollection
.OrderBy(i => i, _sortOrder)
.GroupBy(_groupFunction)
.ToList()
.Select(g => new Grouping<K, T>(g.Key, g));
_items = new ObservableCollection<Grouping<K, T>>(temp);
}
private void HandleCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
var item = (T)(e.NewItems[0]);
var value = _groupFunction.Invoke(item);
// find matching group if exists
var existingGroup = _items.FirstOrDefault(g => g.Key.Equals(value));
if (existingGroup == null)
{
var newlist = new List<T>();
newlist.Add(item);
// find first group where Key is greater than this key
var insertBefore = _items.FirstOrDefault(g => ((g.Key).CompareTo(value)) > 0);
if (insertBefore == null)
{
// not found - add new group to end of list
_items.Add(new Grouping<K, T>(value, newlist));
}
else
{
// insert new group at this index
_items.Insert(_items.IndexOf(insertBefore), new Grouping<K, T>(value, newlist));
}
}
else
{
// find index to insert new item in existing group
int index = existingGroup.ToList().BinarySearch(item, _sortOrder);
if (index < 0)
{
existingGroup.Insert(~index, item);
}
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
var item = (T)(e.OldItems[0]);
var value = _groupFunction.Invoke(item);
var existingGroup = _items.FirstOrDefault(g => g.Key.Equals(value));
if (existingGroup != null)
{
// find existing item and remove
var targetIndex = existingGroup.IndexOf(item);
existingGroup.RemoveAt(targetIndex);
// remove group if zero items
if (existingGroup.Count == 0)
{
_items.Remove(existingGroup);
}
}
}
}
}
可以看出,标头通常由以下行生成:
<TextBlock Text="{Binding Key}" Foreground="CadetBlue" FontSize="18" />
我希望用户能够根据他的选择订购类别。因此,我添加了一个OrderCat
(int)字段,该字段将类别从1编号为(类别编号)。在后面的代码中,我将ListView
不在Category
字段上分组,而是在OrderCat
上分组,并且效果很好(这些分组按选择的顺序出现,而不是按字母顺序出现)。唯一的问题是由于{Binding Key}
,标题显示的是数字(OdreCat
),而不是类别的名称。如何显示与数字相对应的名称?
有人可以帮我吗?
答案 0 :(得分:0)
对于所有试图帮助我的人感到抱歉,但是我无法回答,因为我没有提供重要要素:CatSorter类。 那是必须进行更改的地方。这里是修改之前:
public class CatSorter : Comparer<Achat>
{
public override int Compare(Achat x, Achat y)
{
int result = x.CatArt.CompareTo(y.CatArt);
if (result != 0)
{
return result;
}
else
{
result = x.CatOrder.CompareTo(y.CatOrder);
if (result != 0)
{
return result;
}
else
{
return x.NomArt.CompareTo(y.NomArt);
}
}
}
}
修改后:
public class CatSorter : Comparer<Achat>
{
public override int Compare(Achat x, Achat y)
{
int result = x.CatOrder.CompareTo(y.CatOrder);
if (result != 0)
{
return result;
}
else
{
result = x.CatArt.CompareTo(y.CatArt);
if (result != 0)
{
return result;
}
else
{
return x.NomArt.CompareTo(y.NomArt);
}
}
}
}
在读取和分组Listview的方法中,有必要按文章名称(CatArt)而不是排名编号(CatOrder)对列表进行分组。 这是要纠正的行:
_groupingCollection.ArrangeItems(new CatSorter(), (x => x.CatArt));
完成这些修改后,程序会按类别对文章进行分组,并根据用户选择的顺序对类别进行分类,最重要的是,类别的名称显示为组的标题,而不是排名号。 我希望我的答案很清楚。