【问题标题】:WPF Sorting ItemsControl under DataTemplateDataTemplate下的WPF排序ItemsControl
【发布时间】:2014-04-11 07:33:16
【问题描述】:

我在 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.Tried CollectionViewSource 在 xaml 中的 ControlTemplate 下也不起作用。

                    <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();
    }

【问题讨论】:

    标签: wpf wpf-4.0


    【解决方案1】:

    你有两个选择:

    1 - 在视图模型中对源集合 (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 将显示已排序的项目。

    【讨论】:

    • 对不起。我忘了说我也试过你的选择。
    • 实际上它可以工作,但我忘记将 CollectionViewSource 放在父容器的资源中,所以它抛出了 StaticResourceHolder 异常。我已经用完整的代码更新了答案。
    • 它对我不起作用。我在按钮单击时加载 ObservableCollection 并绑定到 ItemsControl。顺便说一句,为什么 ItemsControls ic 在后面的代码中无法访问。我没有任何线索。
    • 不确定这是否有帮助,但我能够通过在 DataTemplate 上添加 x:Shared=True 来完成这项工作。在我的例子中,我有一个需要使用 CollectionViewSource 的 itemscontrol。这很有帮助。
    【解决方案2】:

    最后我解决了排序问题。 我将 segments(observablecollection) 绑定到 itemscontrol。以前在我后面的代码中直接生成 segments 如下所示

    segments[0].name="GHI";
    segments[0].age=40;
    segments[1].name="ABC";
    segments[1].age=20;
    segments[2].name="DEF";
    segments[2].age=30;
    

    我没有直接生成 segments,而是创建了另一个变量 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);
            }
    

    对我来说效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-11
      • 1970-01-01
      相关资源
      最近更新 更多