Сортировка WPF ListView с DataTemplate вместо DisplayMemberBinding - PullRequest
1 голос
/ 03 августа 2009

Я работаю над сортируемым 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>

Как получить свойство Binding для этого столбца в коде C #?

Ответы [ 4 ]

3 голосов
/ 03 августа 2009

Я написал набор прикрепленных свойств, чтобы сделать именно то, что предложил Кент, вы можете проверить это здесь


РЕДАКТИРОВАТЬ: как требуется, вот пример команды для 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 ...)

0 голосов
/ 23 ноября 2009

Я столкнулся с похожей проблемой сортировки WPF Listview / Gridview, и у меня есть некоторые недостатки, которые затрудняют реализацию предоставленных решений CSharp. По сути, у меня есть существующее приложение ASP.NET с тысячами строк отлаженного VB-кода, а также рабочий SQL для базы данных с более чем 100 таблицами и некоторыми очень сложными объединениями. Мне нужно написать Windows .exe на основе того же приложения, но я хочу использовать WPF для реализации аналогичного графического интерфейса.

Закончив с заявлением об отказе, я столкнулся с проблемой сортировки, поискал в Интернете все отличные общие концепции, подобные приведенным выше, и попытался преобразовать их из CS в VB. Я опытный программист, но я обнаружил, что это просто за пределами моей досягаемости, поэтому я стал другим, и вместо этого разработал свой собственный вид. Это, вероятно, ужаснет пуристов, но я прагматик, и создание коммерческого приложения имеет преимущество.

Чтобы отсортировать сетку, я решил просто использовать события Mouse в заголовках столбцов. DoubleClick для сортировки по возрастанию и 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"

Затем я просто перезагружаю ListViewGrid, используя строковую переменную SqlOrderBy. Единственная проблема, с которой я столкнулся, заключалась в том, что мне пришлось нажать на текст заголовка в заголовке столбца, чтобы он работал. Я решил это, просто добавив символ пробела XML (&#160;), чтобы заполнить ширину столбца. Команда .Trim снова очищает их для работы Select Case. Я до сих пор не понял, как добавить маленькие стрелки вверх и вниз, но здесь важна функциональность, поскольку сейчас это всего лишь косметические штрихи.

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

В заключение позвольте мне добавить, что я полностью осознаю, что если я изменю структуру Gridview, это приведет к перемещению текста заголовка в другое место в OriginalSource, но это проблема, с которой я могу сейчас жить. Я знаю, что это быстрый и грязный обходной путь, и, возможно, есть гораздо лучшие альтернативы, поэтому любые рекомендации будут оценены.

0 голосов
/ 03 августа 2009

встроенный способ WPF будет использовать ICollectionView.

ICollectionView view = CollectionViewSource.GetDefaultView(yourItemsSourceList);
if(view.CanSort)
{
   view.SortDescriptions.Add(...)
}
0 голосов
/ 03 августа 2009

Почему вы пытаетесь сделать это автоматически? Почему бы не предоставить вложенное свойство, которое пользователи могут установить для указания свойства, по которому должен быть отсортирован столбец?

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

Таким образом, вы предлагаете больше свободы реализации, и код будет быстрее и надежнее.

...