使用DataTemplate而不是DisplayMemberBinding对WPF ListView进行排序

时间:2009-08-03 10:05:36

标签: wpf listview binding datatemplate

我正在开发一个可排序的WPF ListView,我已经取得了很多进展。这并不难,因为互联网上已有很多东西。但是我仍然缺少一些信息。

使用类似的列:

<GridViewColumn Width="200" Header="Fahrzeugname" DisplayMemberBinding="{Binding Name}">

我可以这样排序:

Binding columnBinding = column.DisplayMemberBinding as Binding;

if (columnBinding != null)
{
    sorts.Clear();
    sorts.Add(new SortDescription(columnBinding.Path.Path, direction));
    lastColumnSorted = column;
}

但我的问题是我没有DisplayMemberBinding,因为我使用DataTemplate

<DataTemplate>
    <TextBlock Text="{Binding Name}" TextAlignment="Left"/>
</DataTemplate>

如何在C#代码中获取此列的Binding属性?

4 个答案:

答案 0 :(得分:3)

我写了一组附加属性来完成Kent建议的内容,你可以查看here


编辑:根据要求,这是GridViewSort.Command的命令示例:

    private ICommand _sortCommand;
    public ICommand SortCommand
    {
        get
        {
            if (_sortCommand == null)
            {
                _sortCommand = new RelayCommand(SortPersonsBy);
            }
            return _sortCommand;
        }
        set { _sortCommand = value; }
    }

    private void SortPersonsBy(object param)
    {
        string propertyName = param as string;
        ICollectionView view = CollectionViewSource.GetDefaultView(_persons);
        ListSortDirection direction = ListSortDirection.Ascending;
        if (view.SortDescriptions.Count > 0)
        {
            SortDescription currentSort = view.SortDescriptions[0];
            if (currentSort.PropertyName == propertyName)
            {
                if (currentSort.Direction == ListSortDirection.Ascending)
                    direction = ListSortDirection.Descending;
                else
                    direction = ListSortDirection.Ascending;
            }
            view.SortDescriptions.Clear();
        }
        if (!string.IsNullOrEmpty(propertyName))
        {
            view.SortDescriptions.Add(new SortDescription(propertyName, direction));
        }
    }

(它实际上实现了与GridViewSort.AutoSort设置为true时相同的行为...)

答案 1 :(得分:0)

为什么要尝试自动执行此操作?为什么不提供一个附加属性,用户可以设置该属性来指定列的排序属性?

<GridViewColumn s:SortableColumn.SortBy="{Binding Name}" ...>

通过这种方式,您可以提供更多的实施自由,并且代码将更快,更强大。

答案 2 :(得分:0)

WPF内置方式是使用ICollectionView。

ICollectionView view = CollectionViewSource.GetDefaultView(yourItemsSourceList);
if(view.CanSort)
{
   view.SortDescriptions.Add(...)
}

答案 3 :(得分:0)

我正面临类似的WPF Listview / Gridview排序问题,我有一些限制因素使得很难实现所提供的CSharp解决方案。基本上我有一个现有的ASP.NET应用程序,其中包含数千行调试的VB代码,以及为具有100多个表和一些非常复杂的连接的数据库工作的SQL。我必须基于相同的应用程序编写Windows .exe但我想使用WPF来实现类似的图形外观和放大器。感觉。

完成免责声明后,我遇到了排序问题,并在互联网上搜索了上述所有优秀的共享概念,并尝试将它们从CS转换为VB。我是一名经验丰富的程序员,但我发现这简直超出了我的范围,所以我转向了另一个并开发了我自己的排序。它可能会使纯粹主义者感到恐惧,但我是一个实用主义者,并且生产商业应用程序优先。

为了对网格进行排序,我决定只在列标题上使用鼠标事件。 DoubleClick for Ascending排序和MouseRightButtonUp降序。

<GridViewColumn Header="Project Name &#160;&#160;" Width="300" >

Private Sub ListViewGrid_MouseDoubleClick(
    ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles ListingDG.MouseDoubleClick

    Try
        Dim mouseHdrClick As String = DirectCast(DirectCast(e.OriginalSource, System.Object), System.Windows.Controls.TextBlock).Text
        Dim SqlOrderBy As String = ""

        Select Case UCase(mouseHdrClick.Trim)
            Case UCase("Product Name")
                SqlOrderBy = " ORDER BY Product_Name"

然后我只使用SqlOrderBy字符串变量重新加载ListViewGrid。我遇到的唯一问题是我被迫点击列标题中的标题文本以使其工作。我通过附加XML空格字符(&#160;)来填充列宽来解决这个问题。 .Trim命令再次清除它们以使Select Case工作。我仍然没有想出如何添加小向上和向下箭头,但功能是重要的,因为这些只是现在的整容。

<GridViewColumn Header="Project Name &#160;&#160;" Width="300">

最后让我补充一点,我完全清楚如果我更改了Gridview结构,它将导致Header文本移动到OriginalSource的其他位置,但这是我现在可以忍受的问题。我知道这是一个快速的&amp;肮脏的解决方法,可能有更好的选择,所以任何建议都将受到赞赏。