【发布时间】:2023-03-16 02:05:01
【问题描述】:
我正在寻找一种简单的方法来根据控件绑定到的项的隐式 DataTemplate 中指定的属性对 ItemsControl 的项进行排序。在 DataTemplate 上定义属性在这里至关重要,因为我无法在项目本身上添加排序属性。
因此,对于下面的示例 VM 层:
public interface INamed
{
string Name { get; set; }
}
public class FirstModel : INamed
{
public string Name { get; set; }
}
public class SecondModel : INamed
{
public string Name { get; set; }
}
public class ViewModel
{
public ViewModel()
{
Models = new INamed[] { new SecondModel {Name = "Second"}, new FirstModel {Name = "First"}};
}
public IEnumerable<INamed> Models { get; private set; }
}
还有这个附加属性:
public static class AttachedProperties
{
public static int GetSortOrder(DependencyObject obj)
{
return (int)obj.GetValue(SortOrderProperty);
}
public static void SetSortOrder(DependencyObject obj, int value)
{
obj.SetValue(SortOrderProperty, value);
}
public static readonly DependencyProperty SortOrderProperty =
DependencyProperty.RegisterAttached("SortOrder", typeof(int), typeof(AttachedProperties), new PropertyMetadata(0));
}
我有以下 DataTemplate 定义(过于简化):
<DataTemplate DataType="{x:Type local:FirstModel}">
<StackPanel Background="Red" local:AttachedProperties.SortOrder="1">
<Label>First's Name:</Label>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:SecondModel}">
<StackPanel Background="Green" local:AttachedProperties.SortOrder="2">
<Label>Second's Name:</Label>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
某个地方的用法会是这样的:
<ItemsControl ItemsSource="{Binding Models}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
这里项目的顺序应该基于我为数据模板定义的附加属性。在这里没有看到任何直接使用 CollectionViewSource 的选项,可能是我错了...
我看到的当前选项,没有一个太吸引人,是:
- ItemsControl 上的附加行为,遍历每个新项目的可视化树并根据找到的 SortOrder 值对项目进行排序
- 一个自定义的 ItemsControl,它有自己的排序逻辑、面板、二十一点和......你知道的
- 将模型实例包装在某种带有 SortOrder 属性的代理中。这仍然需要一些自定义/用户控件代码隐藏或 ViewModel 类更改
我想念一些更好/更简单的方法吗?
【问题讨论】:
标签: c# wpf sorting mvvm itemscontrol