【问题标题】:WPF MVVM custom Sorting issueWPF MVVM自定义排序问题
【发布时间】:2015-06-16 13:21:59
【问题描述】:

我正在尝试创建自定义排序 WPF 数据网格。我对每次排序都进行了数据库调用。我为此使用了 MVVM。

问题是当我进行数据库调用时,我总是在排序事件中得到列的排序方向始终为空。如果我从排序事件中删除 UpdateData 方法,它将正常工作。所以默认情况下,它会按照我的代码升序排序。谁能帮我获得排序方向或者 ASC 和 DESC 吗?

<DataGrid HorizontalAlignment="Stretch" Grid.Row="1" Grid.Column="0"   SelectedItem="{Binding SelectedPerson}"   ItemsSource="{Binding CollectionView}"  GridLinesVisibility="All"  AutoGenerateColumns="False" SelectionUnit="FullRow" BorderThickness="1"  IsReadOnly="True"  >
        <DataGrid.ContextMenu>
            <ContextMenu>
                <MenuItem Header="ADD" Command="{Binding AddNewPersonCommand}">
                    <MenuItem.Icon>
                        <Image Source="../Icons/Add.png" Height="16" Width="16" Margin="0"   />
                    </MenuItem.Icon>
                </MenuItem>
                <MenuItem Header="EDIT" Command="{Binding EditPersonCommand}">
                    <MenuItem.Icon>
                        <Image Source="../Icons/edit.png" Height="16" Width="16" Margin="0"    />
                    </MenuItem.Icon>
                </MenuItem>
                <MenuItem Header="DELETE">
                    <MenuItem.Icon>
                        <Image Source="../Icons/delete.png" Height="16" Width="16" Margin="0"   />
                    </MenuItem.Icon>
                </MenuItem>
            </ContextMenu>
        </DataGrid.ContextMenu>

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDoubleClick" >
                <i:InvokeCommandAction Command="{Binding EditPersonCommand}"  />
            </i:EventTrigger>
            <i:EventTrigger EventName="Sorting">
                <command:EventToCommand Command="{Binding PersonGridSortingCommand}" PassEventArgsToCommand="True"  />
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Record ID" SortMemberPath="RecordID" Binding="{Binding RecordID}" Width="*" />
            <DataGridTextColumn Header="Last Name" Binding= "{Binding LAST_NAME}" Width="*"  />
            <DataGridTextColumn Header="2nd Last Name" Binding= "{Binding SecondLastName}" Width="*"  />
            <DataGridTextColumn Header="First Name" Binding= "{Binding FIRST_NAME}" Width="*" />
            <DataGridTextColumn Header="Date Of Birth" Binding= "{Binding Date_Of_Birth}"  Width="*"   />
            <!--<DataGridTextColumn Header="Town" Binding= "{Binding PrimaryAddress.City}" Width="*"   />-->
        </DataGrid.Columns>
    </DataGrid>


    private ICollectionView _collectionView;

    public ICollectionView CollectionView
    {
        get
        {
            return _collectionView;
        }
        set
        {
            _collectionView = value;
            OnPropertyChanged("CollectionView");
        }
    }




    public async Task UpdateData(string sortCoulmnName = null, string sortDirection = null)
    {
        var lstPersons = await PersonDAO.SelectAll(PagerViewModel.CurrentPage, PagerViewModel.PageSize, sortCoulmnName, sortDirection);
        if (lstPersons.DataSource != null) { }
        Persons = new ObservableCollection<PersonDTO>((PersonListDTO)lstPersons.DataSource);
        CollectionView = CollectionViewSource.GetDefaultView(Persons);                    
    }

    public async void Sorting(DataGridSortingEventArgs e)
    {
        e.Handled = true;
        ListSortDirection direction = (e.Column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending;
        e.Column.SortDirection = direction;
        string dir = direction.ToString() == "Ascending" ? "ASC" : "DESC";
        await UpdateData(e.Column.SortMemberPath, dir);
        CollectionView.SortDescriptions.Clear();
        CollectionView.SortDescriptions.Add(new SortDescription(e.Column.SortMemberPath, direction));

    }

【问题讨论】:

  • 你不是对集合进行双重排序吗?首先在UpdateData 方法中(我猜)然后将SortDescription 添加到集合视图中?
  • 我在数据网格中有 20 条记录的分页,但我想从数据库表的所有记录中进行排序。所以我使用 UpdateData 方法从整个表的数据库中获取排序数据。

标签: c# asp.net wpf sorting mvvm


【解决方案1】:

由于您将事件标记为已处理 (e.Handled = true),因此您有效地阻止了 DataGrid 排序,并且 SortDirection 永远不会改变。

您必须自己管理排序方向。但它应该像这样简单:

private ListSortDirection lastSortDirection;

private string lastSortMemberPath;

public async void Sorting(DataGridSortingEventArgs e)
{
    e.Handled = true;

    if (e.Column.SortMemberPath == lastSortMemberPath)
    {
        if (lastSortDirection == ListSortDirection.Ascending)
            e.Column.SortDirection = ListSortDirection.Descending;
        else
            e.Column.SortDirection = ListSortDirection.Ascending;
    }
    else
        e.Column.SortDirection = ListSortDirection.Ascending;

    string dir = (e.Column.SortDirection == ListSortDirection.Ascending) ? "ASC" : "DESC";
    lastSortDirection = e.Column.SortDirection;
    lastSortMemberPath = e.Column.SortMemberPath;
    await UpdateData(e.Column.SortMemberPath, dir);

    // In my opinion, this last bit is redundant since data should come already sorted
    CollectionView.SortDescriptions.Clear();
    CollectionView.SortDescriptions.Add(new SortDescription(e.Column.SortMemberPath, e.Column.SortDirection));
}

【讨论】:

  • 谢谢。上面的解决方案对我来说很好。但如果有任何其他解决方案不需要在排序事件之外声明变量,我们将不胜感激。
  • 如果您不想自己管理排序方向,则必须从原始代码中删除 e.Handled = true 并让 DataGrid 自行排序(无论您是否还对来自服务器的数据进行排序) )。
  • 我以前试过。但它只对当前页面大小内的数据进行排序。意味着我的 DataGrid 页面大小为 20。因此它将在 20 条记录内排序。但我需要从整个数据库表中排序。
  • 我并不是要你完全停止处理 Sorting 事件,只是要删除 e.Handled = true 行。您仍然可以使用 UpdateData 方法从数据库中获取排序后的数据,但您也可以让 DataGrid 自行排序。这两件事并不相互排斥。
猜你喜欢
  • 1970-01-01
  • 2014-03-09
  • 2013-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-25
  • 1970-01-01
相关资源
最近更新 更多