HeaderTemplate 中的 GridViewColumn 命令 [英] GridViewColumn Command in HeaderTemplate

查看:25
本文介绍了HeaderTemplate 中的 GridViewColumn 命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 GridViewColumn 的 GridView,标题使用带有 textblox 的模板来显示列名.我想要一个命令附加到此列,基本上当用户单击该列时,我的 VM 中的命令会被调用?

I have a GridView with GridViewColumn, the header uses a template with a textblox to show the column name. I want a command attached to this column, basically when the user clicks the column, a command in my VM gets called ?

这是为了排序.

谢谢

推荐答案

帮助您可能为时已晚,但对于其他正在寻找答案的人,您可以使用 附加行为 和 GridViewColumnHeader.Click 事件(请参阅 这篇 MSDN 文章 关于在单击标题项时对 GridView 进行排序).

Probably too late to help you but for anyone else looking for an answer, you can do this using Attached Behaviours and the GridViewColumnHeader.Click event (see this MSDN article on sorting a GridView on header item click).

我的代码如下;XAML:

My code was as follows; XAML:

<ListView Width="Auto" Height="Auto" Margin="12,12,12,12"
  ItemsSource="{Binding SearchResults}" 
  behav:GridViewColumnHeaderClick.Command="{Binding SortViewCommand}">

(其中 'behav' 是我的附加行为的命名空间).附加的行为类如下所示:

(where 'behav' is the namespace for my attached behaviours). The attached behaviour classes look like this:

public class GridViewColumnHeaderClick
{
    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(GridViewColumnHeaderClick), new UIPropertyMetadata(null,
            GridViewColumnHeaderClick.CommandChanged));

    public static readonly DependencyProperty CommandBehaviourProperty =
        DependencyProperty.RegisterAttached("CommandBehaviour", typeof(GridViewColumnHeaderClickCommandBehaviour), typeof(GridViewColumnHeaderClick),
            new UIPropertyMetadata(null));

    public static ICommand GetCommand(DependencyObject obj)
    {
        return (ICommand)obj.GetValue(CommandProperty);
    }

    public static void SetCommand(DependencyObject obj, ICommand value)
    {
        obj.SetValue(CommandProperty, value);
    }

    public static GridViewColumnHeaderClickCommandBehaviour GetCommandBehaviour(DependencyObject obj)
    {
        return (GridViewColumnHeaderClickCommandBehaviour)obj.GetValue(CommandBehaviourProperty);
    }

    public static void SetCommandBehaviour(DependencyObject obj, GridViewColumnHeaderClickCommandBehaviour value)
    {
        obj.SetValue(CommandBehaviourProperty, value);
    }

    private static void CommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        GridViewColumnHeaderClick.GetOrCreateBehaviour(sender).Command = e.NewValue as ICommand;
    }

    private static GridViewColumnHeaderClickCommandBehaviour GetOrCreateBehaviour(DependencyObject element)
    {
        GridViewColumnHeaderClickCommandBehaviour returnVal = GridViewColumnHeaderClick.GetCommandBehaviour(element);

        if (returnVal == null)
        {
            ListView typedElement = element as ListView;

            if (typedElement == null)
            {
                throw new InvalidOperationException("GridViewColumnHeaderClick.Command property can only be set on instances of ListView");
            }

            returnVal = new GridViewColumnHeaderClickCommandBehaviour(typedElement);

            GridViewColumnHeaderClick.SetCommandBehaviour(element, returnVal);
        }

        return returnVal;
    }
}

和:

public class GridViewColumnHeaderClickCommandBehaviour
{
    public GridViewColumnHeaderClickCommandBehaviour(ListView element)
    {
        element.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(this.ClickEventHandler));
    }

    public ICommand Command { get; set; }

    private void ClickEventHandler(object sender, RoutedEventArgs e)
    {
        ICommand localCommand = this.Command;
        object parameter = e.OriginalSource as GridViewColumnHeader;

        if ((localCommand != null) && localCommand.CanExecute(parameter))
        {
            localCommand.Execute(parameter);
        }
    }
}

然后您的命令可以基于 MSDN 文章中描述的事件处理程序:

and then your command can be based on the event handler described in the MSDN article:

    private void SortResults(string sortBy, ListSortDirection direction)
    {
        ICollectionView dataView = CollectionViewSource.GetDefaultView(this.SearchResults);    // where SearchResults is the data to which the ListView is bound
        dataView.SortDescriptions.Clear();

        SortDescription sortDescription = new SortDescription(sortBy, direction);
        dataView.SortDescriptions.Add(sortDescription);
        dataView.Refresh();
    }

    private void SortViewCommandHandler(object parameter)
    {
        GridViewColumnHeader typedParameter = parameter as GridViewColumnHeader;

        ListSortDirection direction;

        if (typedParameter != null)
        {
            if (typedParameter.Role != GridViewColumnHeaderRole.Padding)
            {
                if (typedParameter != this.previousSortHeader)
                {
                    direction = ListSortDirection.Ascending;
                }
                else
                {
                    if (this.previousSortDirection == ListSortDirection.Ascending)
                    {
                        direction = ListSortDirection.Descending;
                    }
                    else
                    {
                        direction = ListSortDirection.Ascending;
                    }
                }

                string headerLabel = typedParameter.Column.Header as string;

                this.SortResults(headerLabel, direction);

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

                // Remove arrow from previously sorted header
                if ((this.previousSortHeader != null) && (this.previousSortHeader != typedParameter))
                {
                    this.previousSortHeader.Column.HeaderTemplate = null;
                }

                this.previousSortHeader = typedParameter;
                this.previousSortDirection = direction;
            }
        }
    }

我还没有想到一种 MVVM 风格的方式来设置标题模板(视图显然应该绑定到这里的某些东西)所以你自己在那里!

I haven't yet thought of an MVVM-ish way to set the header template (the view should obviously be bound to something in here) so you're on your own there!

请注意,我在实现附加行为时与 Josh Smith 的文章略有不同 - 使用单独的类使多个有状态处理程序比使用静态事件处理程序方法更容易,因此这是我通常遵循的模式.

Note that I'm deviating slightly from the Josh Smith article in my implementation of the attached behaviour - having a separate class makes multiple stateful handlers easier than using a static event handler method, so it's a pattern I follow in general.

这篇关于HeaderTemplate 中的 GridViewColumn 命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆