私は GridViewColumn を持つ GridView を持っています。ヘッダーは textblox を持つテンプレートを使用して列名を表示します。この列にコマンドを追加したいのですが、基本的にユーザーが列をクリックすると、VM のコマンドが呼び出されますか?
これはソート用です。
ありがとう
私は GridViewColumn を持つ GridView を持っています。ヘッダーは textblox を持つテンプレートを使用して列名を表示します。この列にコマンドを追加したいのですが、基本的にユーザーが列をクリックすると、VM のコマンドが呼び出されますか?
これはソート用です。
ありがとう
おそらく手遅れかもしれませんが、答えを探している他の人にとっては、Attached Behaviorsと GridViewColumnHeader.Click イベントを使用してこれを行うことができます (ヘッダー項目のクリックで GridView をソートする方法に関するこの MSDN の記事を参照してください)。
私のコードは次のとおりです。XAML:
<ListView Width="Auto" Height="Auto" Margin="12,12,12,12"
ItemsSource="{Binding SearchResults}"
behav:GridViewColumnHeaderClick.Command="{Binding SortViewCommand}">
(「behav」は、添付された動作の名前空間です)。アタッチされた動作クラスは次のようになります。
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 の記事で説明されているイベント ハンドラーに基づくことができます。
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 風の方法はまだ考えていません (ビューは明らかにここで何かにバインドする必要があります)。
添付されたビヘイビアーの実装において、Josh Smith の記事から少し逸脱していることに注意してください。個別のクラスを使用すると、静的イベント ハンドラー メソッドを使用するよりも複数のステートフル ハンドラーを簡単に作成できるため、一般的に従うパターンです。
ヘッダー テンプレートのテキストブロックをボタンに置き換えて、コマンドをアタッチできます。必要に応じて、ボタンのスタイルを設定して境界線を削除できます。