4

私は列として、別の列として with を持っていGridViewます。コードは次のとおりです。CheckBoxTextBlockXAML

<ListView.View>
    <GridView>
        <GridView.ColumnHeaderContainerStyle>
            <Style>
                <Setter Property="UIElement.Visibility"
                        Value="Collapsed"/>
            </Style>
        </GridView.ColumnHeaderContainerStyle>

        <GridViewColumn>
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox Tag="{Binding}"
                              IsChecked="{Binding Path=IsFormChecked, Mode=TwoWay}"
                              IsEnabled="{Binding Path=IsUnRestricted}"
                              IsThreeState="False" 
                              UIElement.KeyUp="CheckBox_KeyUp" />
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>

        <GridViewColumn Width="auto">
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Width="600"
                               Tag="{Binding}"
                               IsEnabled="{Binding Path=IsUnRestricted}"
                               Text="{Binding Path=FormName}" 
                               MouseUp="TextBlock_MouseUp">
                        <TextBlock.ToolTip>
                            <TextBlock Text="{Binding Path=FormName}"/>
                        </TextBlock.ToolTip>
                    </TextBlock>
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>
    </GridView>
</ListView.View>

GridViewキーボードでこれにアクセスすると、行全体が選択されます(CheckBoxおよびTextBlock)。この時点でスペースキーを押しても何も起こりません。キーボードでアクセスしたい場合はCheckBox、タブキーをもう一度押してチェックボックスにフォーカスを設定し、スペースバーを使用してチェック/チェックを外す必要があります。私がやりたいのは、スペースバーを1回押すだけでチェックボックスをオン/オフしたい行にフォーカスがあるときです。

4

2 に答える 2

3

現在選択されているアイテムにバインディングがある場合は、次のPreviewKeyUpイベントを処理できますListView

<ListView PreviewKeyUp="OnGridKeyUp"
          SelectedItem="{Binding MySelectedItem}"
          SelectionMode="Single"
          ItemsSource="{Binding ItemsList}">
    ...
</ListView>

コードビハインドでこれを処理します。

private void OnGridKeyUp(object sender, KeyEventArgs e)
{
    if(vm.mySelectedItem != null && e.Key == Key.Space)
    {
        vm.MySelectedItem.IsChecked = !vm.MySelectedItem.IsChecked;
        e.Handled = true; //this is necessary because otherwise when the checkbox cell is selected, it will apply this keyup and also apply the default behavior for the checkbox
    }
}

これには明らかに、コード ビハインドからビューモデルを処理する必要があります。これは次のように簡単です。

var vm = DataContext as MyViewModel;

これは最もMVVMの方法ではありませんが、ちょっと...

于 2013-06-05T13:09:50.797 に答える
1

これを行うために、より MVVM に適した方法を作成しました。

ステップ 1: この動作を作成する

public class ToggleSelectOnSpace : Behavior<DataGrid>
{
    public static readonly DependencyProperty toggleSelectCommand =
        DependencyProperty.Register("ToggleSelectCommand",
        typeof(ICommand),
        typeof(ToggleSelectOnSpace));

    public ICommand ToggleSelectCommand
    {
        get { return this.GetValue(toggleSelectCommand) as ICommand; }
        set { this.SetValue(toggleSelectCommand, value); }
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        this.AssociatedObject.PreviewKeyUp += PreviewKeyUp;
    }

    protected override void OnDetaching()
    {
        this.AssociatedObject.PreviewKeyUp -= PreviewKeyUp;
        base.OnDetaching();
    }

    private void PreviewKeyUp(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Space)
        {
            if (ToggleSelectCommand != null)
            {
                ToggleSelectCommand.Execute(this.AssociatedObject.SelectedItems);
            }
        }
    }
}

ステップ 2: View Model にこのようなコマンドを実装します (コマンドのメソッド ロジック)

    private void ToggleSelectParticipant(object selectedObjects)
    {
        var items = (System.Collections.IList)selectedObjects;
        var collection = items.Cast<MyItemType>().ToList();
        bool selection = !collection.All(x => x.IsSelected);
        foreach (var item in collection)
            item.IsSelected = selection;
    }

ステップ 3: 動作をグリッドにバインドし、コマンドを動作にバインドする

<DataGrid>
    <i:Interaction.Behaviors>
        <shared:ToggleSelectOnSpace ToggleSelectCommand="{Binding Data.ToggleSelectParticipantCommand, Source={StaticResource BindingProxy}}" />
    </i:Interaction.Behaviors>
...
</DataGrid>

( BindingProxy ソースに関する情報)

于 2014-06-20T12:53:30.313 に答える