我在DataTemplate下使用ItemsControl。我想使用id列对ItemsControl ic 进行排序。
<DataTemplate x:Key="With">
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock Text="{Binding Path=fil}" Style="{StaticResource Fixed}" Margin="0,0,6,8" />
<mui:ModernButton IconData="{StaticResource PlayIconData}" Click="FullPlayback" Margin="0,0,6,8" ></mui:ModernButton>
</StackPanel>
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal">
<TextBlock Text="{Binding Path=e1}" Foreground="Red" Style="{StaticResource Fixed}" Margin="0,0,6,8" />
<TextBlock Text="{Binding Path=m1}" Foreground="LightSalmon" Style="{StaticResource Fixed}" Margin="0,0,6,8" />
<TextBlock Text="{Binding Path=n1}" Foreground="Orange" Style="{StaticResource Fixed}" Margin="0,0,6,8" />
<TextBlock Text="{Binding Path=m2}" Foreground="LightGreen" Style="{StaticResource Fixed}" Margin="0,0,6,8" />
<TextBlock Text="{Binding Path=m3}" Foreground="Green" Style="{StaticResource Fixed}" Margin="0,0,6,8" />
<TextBlock Text="{Binding ElementName=H1, Path=Items.Count,Mode=OneWay}" Style="{StaticResource Fixed}" Margin="0,0,6,8" />
</StackPanel>
<ItemsControl Name="ic" DockPanel.Dock="Bottom" ItemsSource="{Binding Path=seg}" ItemsPanel="{StaticResource HSPanel}">
<ControlTemplate TargetType="ItemsControl">
<Border>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</DockPanel>
</DataTemplate>
我尝试了下面的选项,但排序不起作用。
1.在用户控件的构造函数中进行了如下排序(代码隐藏)
ic.Items.SortDescriptions.Clear();
ic.Items.SortDescriptions.Add(new SortDescription("id", ListSortDirection.Ascending));
ic.Items.Refresh();
但我无法在后面的代码中访问 ic 。错误说“ic在当前环境中不存在”
2.在xaml中的ItemsControl下使用CollectionViewSource,它也无效。
<ItemsControl x:Name="ic" DockPanel.Dock="Bottom" ItemsSource="{Binding Path=segments}" ItemsPanel="{StaticResource HSPanel}">
<ItemsControl.Resources>
<CollectionViewSource x:Key="segments" Source="{Binding seg}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="id" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</ItemsControl.Resources>
<ItemsControl.Template>
3.在xaml中的ControlTemplate下使用CollectionViewSource,它也无效。
<ControlTemplate TargetType="ItemsControl">
<ControlTemplate.Resources>
<CollectionViewSource x:Key="segments" Source="{Binding seg}" >
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="sortId" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</ControlTemplate.Resources>
但是我初始化了 ic 的Loaded事件,并尝试从那里进行排序。在这种情况下,首先加载页面时,项目不会被排序。但是,当我移动到另一个用户控件并回到当前用户控件时,这些项目看起来很完美。
private void ic_Loaded(object sender, RoutedEventArgs e)
{
ItemsControl ic = (ItemsControl)sender;
ic.Items.SortDescriptions.Clear();
ic.Items.SortDescriptions.Add(new SortDescription("id", ListSortDirection.Ascending));
ic.Items.Refresh();
}
答案 0 :(得分:4)
您有两种选择:
1 - 在View Model中对源集合(seg)进行排序。
2 - 使用CollectionViewSource(http://msdn.microsoft.com/fr-fr/library/system.windows.data.collectionviewsource.aspx)。 这是一个完整的工作例子:
我已将此代码添加到空的WPF窗口中:
public class SomeVM
{
public ObservableCollection<SomeItemVM> Items { get; set; }
public SomeVM()
{
Items = new ObservableCollection<SomeItemVM>();
}
}
public class SomeItemVM
{
public string id { get; set; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//Create some VM
SomeVM data = new SomeVM();
data.Items.Add(new SomeItemVM() { id = "3" });
data.Items.Add(new SomeItemVM() { id = "4" });
data.Items.Add(new SomeItemVM() { id = "1" });
data.Items.Add(new SomeItemVM() { id = "2" });
this.DataContext = data;
}
}
然后在XAML中添加一个内容控件来保存VM和一个DataTemplate,它将描述VM的显示方式:
<Window.Resources>
<DataTemplate x:Key="With">
<DockPanel>
<DockPanel.Resources>
<!-- CollectionViewSource should be declared as a resource of parent container of the ItemsControl.
Otherwise there will be an exception of StaticResourceHolder -->
<CollectionViewSource x:Key="segments" Source="{Binding Items}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="id" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</DockPanel.Resources>
<ItemsControl Name="ic" DockPanel.Dock="Bottom" ItemsSource="{Binding Source={StaticResource segments}}">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding id}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ContentControl Content="{Binding}" ContentTemplate="{StaticResource With}"/>
</Grid>
生成的ItemsControl将显示已排序的项目。
答案 1 :(得分:0)
最后我解决了排序问题。 我将段(observablecollection&lt; seg&gt;)绑定到itemscontrol。以前在代码背后我直接生成细分,如下所示
segments[0].name="GHI";
segments[0].age=40;
segments[1].name="ABC";
segments[1].age=20;
segments[2].name="DEF";
segments[2].age=30;
我没有直接生成段,而是创建了另一个变量objSegments并生成了如下所示的值。
objSegments[0].name="GHI";
objSegments[0].age=40;
objSegments[1].name="ABC";
objSegments[1].age=20;
objSegments[2].name="DEF";
objSegments[2].age=30;
生成所有值后,使用以下代码完成排序并分配到段。
ObservableCollection<seg> sortedSegments = new ObservableCollection<seg>(objSegments.OrderBy(c => c.id));
foreach (var objSeg in sortedSegments)
{
segments.Add(objSeg);
}
它对我来说很好。