Хобрук: Ваш путь к мастерству в программировании

Как получить имя привязки из DataTemplate

Я пытаюсь отсортировать ListView по заголовкам.

Я следую этому пример MSDN, с указанием чередования здесь - где это line работает, если бы я использовал прямую привязку:

GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
string sortString = ((Binding)headerClicked.Column.DisplayMemberBinding).Path.Path

Но проблема в том, что я не привязываю столбцы напрямую с помощью DisplayMemberBinding="{Binding PVNum}", а использую CellTemplate:

<ListView.Resources>
    <DataTemplate x:Key="NumberTemplate">
        <TextBlock Text="{Binding PVNum}" TextAlignment="Center"  />
    </DataTemplate>
</ListView.Resources>

<ListView.View>
  <GridView AllowsColumnReorder="False">
     <GridView.Columns>
        <GridViewColumn Header=" " CellTemplate="{StaticResource NumberTemplate}"/>
      </GridView.Columns>
   </GridView>
</ListView.View>

Итак, мой вопрос - как мне получить эту строку «PVNum» в коде?

Я пробовал это, хотя s имеет значение null, поэтому я думаю, что я отключен:

 var t = headerClicked.Column.CellTemplate.LoadContent() as TextBlock;
 var s = t.GetBindingExpression(TextBox.TextProperty);

Какие-либо предложения?

24.10.2017

Ответы:


1

Это должно быть свойство Text Block .Text:

var t = headerClicked.Column.CellTemplate.LoadContent() as TextBlock;
var s = t.GetBindingExpression(TextBlock.TextProperty);
string sourcePropertyName = s.ParentBinding.Path.Path;
25.10.2017

2

Возможное решение - определить присоединенное свойство для GridViewColumn:

public class GridViewColumnAttachedProperties
{
    public static readonly DependencyProperty SortPropertyNameProperty = DependencyProperty.RegisterAttached(
        "SortPropertyName", typeof(string), typeof(GridViewColumnAttachedProperties), new PropertyMetadata(default(string)));

    public static void SetSortPropertyName(DependencyObject element, string value)
    {
        element.SetValue(SortPropertyNameProperty, value);
    }

    public static string GetSortPropertyName(DependencyObject element)
    {
        return (string) element.GetValue(SortPropertyNameProperty);
    }
}

В XAML вы устанавливаете вложенные свойства в Path, используемые в Binding внутри шаблонов. На основе примера с сайта MSDN:

<ListView x:Name='lv' Height="150" HorizontalAlignment="Center" VerticalAlignment="Center" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">
    <ListView.Resources>
        <DataTemplate x:Key="YearTemplate">
            <TextBlock Text="{Binding Year}" TextAlignment="Center"  />
        </DataTemplate>
        <DataTemplate x:Key="MonthTemplate">
            <TextBlock Text="{Binding Month}" TextAlignment="Center"  />
        </DataTemplate>
        <DataTemplate x:Key="DayTemplate">
            <TextBlock Text="{Binding Day}" TextAlignment="Center"  />
        </DataTemplate>
    </ListView.Resources>

    <ListView.ItemsSource>
        <collections:ArrayList>
            <system:DateTime>1993/1/1 12:22:02</system:DateTime>
            <system:DateTime>1993/1/2 13:2:01</system:DateTime>
            <system:DateTime>1997/1/3 2:1:6</system:DateTime>
            <system:DateTime>1997/1/4 13:6:55</system:DateTime>
            <system:DateTime>1999/2/1 12:22:02</system:DateTime>
            <system:DateTime>1998/2/2 13:2:01</system:DateTime>
            <system:DateTime>2000/2/3 2:1:6</system:DateTime>
            <system:DateTime>2002/2/4 13:6:55</system:DateTime>
            <system:DateTime>2001/3/1 12:22:02</system:DateTime>
            <system:DateTime>2006/3/2 13:2:01</system:DateTime>
            <system:DateTime>2004/3/3 2:1:6</system:DateTime>
            <system:DateTime>2004/3/4 13:6:55</system:DateTime>
        </collections:ArrayList>
    </ListView.ItemsSource>

    <ListView.View>
        <GridView>
            <GridViewColumn CellTemplate="{StaticResource YearTemplate}" local:GridViewColumnAttachedProperties.SortPropertyName="Year" />
            <GridViewColumn CellTemplate="{StaticResource MonthTemplate}" local:GridViewColumnAttachedProperties.SortPropertyName="Month" />
            <GridViewColumn CellTemplate="{StaticResource DayTemplate}" local:GridViewColumnAttachedProperties.SortPropertyName="Day" />
        </GridView>
    </ListView.View>
</ListView>

А в обработчике событий Click вы можете просто получить значение присоединенного свойства с помощью string bindingName = headerClicked.Column.GetValue(GridViewColumnAttachedProperties.SortPropertyNameProperty) as string;. На основе примера MSDN:

GridViewColumnHeader _lastHeaderClicked;
ListSortDirection _lastDirection = ListSortDirection.Ascending;

private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
{
    GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;

    if (headerClicked != null)
    {
        if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
        {
            ListSortDirection direction;
            if (!ReferenceEquals(headerClicked, _lastHeaderClicked))
            {
                direction = ListSortDirection.Ascending;
            }
            else
            {
                if (_lastDirection == ListSortDirection.Ascending)
                {
                    direction = ListSortDirection.Descending;
                }
                else
                {
                    direction = ListSortDirection.Ascending;
                }
            }

            string bindingName = headerClicked.Column.GetValue(GridViewColumnAttachedProperties.SortPropertyNameProperty) as string;
            Sort(bindingName, direction);

            if (direction == ListSortDirection.Ascending)
            {
                headerClicked.Column.HeaderTemplate = Resources["HeaderTemplateArrowUp"] as DataTemplate;
            }
            else
            {
                headerClicked.Column.HeaderTemplate = Resources["HeaderTemplateArrowDown"] as DataTemplate;
            }

            // Remove arrow from previously sorted header  
            if (_lastHeaderClicked != null && !ReferenceEquals(_lastHeaderClicked, headerClicked))
            {
                _lastHeaderClicked.Column.HeaderTemplate = null;
            }

            _lastHeaderClicked = headerClicked;
            _lastDirection = direction;
        }
    }
}

private void Sort(string sortBy, ListSortDirection direction)
{
    ICollectionView dataView = CollectionViewSource.GetDefaultView(lv.ItemsSource);

    dataView.SortDescriptions.Clear();
    SortDescription sd = new SortDescription(sortBy, direction);
    dataView.SortDescriptions.Add(sd);
    dataView.Refresh();
}
25.10.2017
Новые материалы

Аргументы прогрессивного улучшения почти всегда упускают суть
В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

Введение в Джанго Фреймворк
Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

стройный-i18следующий
Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..

Обзор 20 основных и современных методов работы с массивами в JavaScript
Вы знаете их всех? В этом коротком посте я покажу сводку методов, доступных в JavaScript для работы с массивами. Я надеюсь, что вы найдете это полезным! В конце поста вы найдете ссылку на..

Да, но я чувствую необходимость указать, что это или не единственные два.
Да, но я чувствую необходимость указать, что это или не единственные два. Обучение с подкреплением (в качестве примера) также является важным.