5

プロパティを に設定しListViewて、WinForms と同等のものを実現しようとしています。視覚的には、以下は正常に機能します。私のファイル名は上から下に移動し、新しい列に折り返されます。ViewView.ListListbox

私が使用している基本的な XAML は次のとおりです。

<ListBox Name="thelist"
    IsSynchronizedWithCurrentItem="True"
    ItemsSource="{Binding}"
    ScrollViewer.VerticalScrollBarVisibility="Disabled">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel IsItemsHost="True"
                Orientation="Vertical" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

ただし、デフォルトの矢印キー ナビゲーションは折り返されません。列の最後の項目が選択されている場合、下矢印を押しても次の列の最初の項目には移動しません。

私はKeyDownこのようにイベントを処理しようとしました:

private void thelist_KeyDown( object sender, KeyEventArgs e ) {
    if ( object.ReferenceEquals( sender, thelist ) ) {
        if ( e.Key == Key.Down ) {
            e.Handled = true;
            thelist.Items.MoveCurrentToNext();
        }
        if ( e.Key == Key.Up ) {
            e.Handled = true;
            thelist.Items.MoveCurrentToPrevious();
        }
    }
}

これにより、私が望んでいた最後の列から次の列の最初への動作が生成されますが、左矢印と右矢印の処理にも奇妙な点が生じます。上/下矢印を使用してある列から次/前の列にラップするときはいつでも、左または右矢印キーを 1 回続けて使用すると、ラップが発生する直前に選択されていた項目の左または右に選択が移動します。

リストが文字列 "0001" から "0100" で満たされ、列ごとに 10 個の文字列があるとします。下矢印キーを使用して「0010」から「0011」に移動し、次に右矢印キーを押すと、選択が「0010」のすぐ右にある「0020」に移動します。「0011」が選択され、上矢印キーを使用して選択を「0010」に移動した場合、右矢印キーを押すと選択が「0021」(「0011」の右側) に移動し、左矢印キーを押すと選択が移動します。矢印キーで選択を「0001」に移動します。

目的の列ラップ レイアウトと矢印キー ナビゲーションを達成するための助けをいただければ幸いです。

(技術的には回答であるため、編集は私自身の回答に移動しました。)

4

2 に答える 2

8

イベントの処理でラップアラウンドするとKeyDown、選択は正しい項目に変更されますが、フォーカスは古い項目にあることがわかりました。

これが更新されたKeyDownイベントハンドラです。Binding により、Itemsコレクションは s ではなく実際のアイテムを返すため、呼び出す必要がある実際のアイテムListBoxItemを取得するために、最後近くで呼び出しを行うListBoxItem必要がありますFocus()。と の呼び出しを交換することで、最後のアイテムから最初のアイテムへのラップ、およびその逆のラップを実現できMoveCurrentToLast()ますMoveCurrentToFirst()

private void thelist_KeyDown( object sender, KeyEventArgs e ) {
    if ( object.ReferenceEquals( sender, thelist ) ) {
        if ( thelist.Items.Count > 0 ) {
            switch ( e.Key ) {
                case Key.Down:
                    if ( !thelist.Items.MoveCurrentToNext() ) {
                        thelist.Items.MoveCurrentToLast();
                    }
                    break;

                case Key.Up:
                    if ( !thelist.Items.MoveCurrentToPrevious() ) {
                        thelist.Items.MoveCurrentToFirst();
                    }
                    break;

                default:
                    return;
            }

            e.Handled = true;
            ListBoxItem lbi = (ListBoxItem) thelist.ItemContainerGenerator.ContainerFromItem( thelist.SelectedItem );
            lbi.Focus();
        }
    }
}
于 2008-09-25T20:40:36.070 に答える
5

たとえば、KeyboardNavigation.DirectionalNavigation を使用して、イベント リスナーなしで実行できるはずです。

<ListBox Name="thelist"
         IsSynchronizedWithCurrentItem="True"
         ItemsSource="{Binding}"
         ScrollViewer.VerticalScrollBarVisibility="Disabled"
         KeyboardNavigation.DirectionalNavigation="Cycle">
于 2008-11-06T15:11:06.980 に答える