سؤال

أحاول تحقيق ما يعادل WinForms ListView مع ل View خاصية تعيين ل View.List.بصريا، ما يلي يعمل بشكل جيد.أسماء الملفات في ملفي Listbox انتقل من الأعلى إلى الأسفل، ثم قم بالالتفاف إلى عمود جديد.

إليك 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();
        }
    }
}

ينتج عن ذلك سلوك العمود الأخير إلى سلوك العمود التالي الذي أردته، ولكنه ينتج أيضًا غرابة في التعامل مع السهم الأيمن والأيسر.في أي وقت يتم فيه الالتفاف من عمود إلى العمود التالي/السابق باستخدام الأسهم لأعلى/لأسفل، يؤدي استخدام واحد لاحق لمفتاح السهم لليسار أو لليمين إلى نقل التحديد إلى يسار أو يمين العنصر الذي تم تحديده قبل حدوث الالتفاف مباشرة.

افترض أن القائمة مليئة بالسلاسل من "0001" إلى "0100" مع 10 سلاسل لكل عمود.إذا استخدمت مفتاح السهم لأسفل للانتقال من "0010" إلى "0011"، ثم اضغط على مفتاح السهم الأيمن، فسينتقل التحديد إلى "0020"، إلى يمين "0010" مباشرةً.إذا تم تحديد "0011" واستخدمت مفتاح السهم لأعلى لنقل التحديد إلى "0010"، فإن الضغط على مفاتيح الأسهم اليمنى ينقل التحديد إلى "0021" (على يمين "0011"، والضغط على اليسار ينقل مفتاح السهم التحديد إلى "0001".

سيكون موضع تقدير أي مساعدة في تحقيق تخطيط التفاف العمود المطلوب والتنقل باستخدام مفتاح السهم.

(تم نقل التعديلات إلى إجابتي الخاصة، لأنها من الناحية الفنية إجابة.)

هل كانت مفيدة؟

المحلول

اتضح أنه عندما يلتف الأمر في طريقة تعاملي مع ملف KeyDown الحدث، يتغير التحديد إلى العنصر الصحيح، ولكن التركيز يكون على العنصر القديم.

هنا هو المحدث KeyDown معالج الأحداث.بسبب الربط، Items تقوم المجموعة بإرجاع العناصر الفعلية الخاصة بي بدلاً من ListBoxItems، لذلك لا بد لي من إجراء مكالمة بالقرب من النهاية للحصول على الفعلي 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();
        }
    }
}

نصائح أخرى

يجب أن تكون قادرًا على القيام بذلك بدون مستمع الحدث باستخدام KeyboardNavigation.DirectionalNavigation، على سبيل المثال.

<ListBox Name="thelist"
         IsSynchronizedWithCurrentItem="True"
         ItemsSource="{Binding}"
         ScrollViewer.VerticalScrollBarVisibility="Disabled"
         KeyboardNavigation.DirectionalNavigation="Cycle">
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top