Microsoft-ui-xaml: ScrollViewer أكثر مرونة

تم إنشاؤها على ١٩ ديسمبر ٢٠١٨  ·  61تعليقات  ·  مصدر: microsoft/microsoft-ui-xaml

هذا نموذج لميزة جديدة أو مقترحات واجهة برمجة التطبيقات. على سبيل المثال ، يمكنك استخدام هذا لاقتراح واجهة برمجة تطبيقات جديدة على نوع موجود ، أو فكرة لعنصر تحكم جديد لواجهة المستخدم. لا بأس إذا لم يكن لديك كل التفاصيل: يمكنك البدء بالملخص والمسوغات. يصف هذا الارتباط ميزة WinUI / عملية اقتراح واجهة برمجة التطبيقات: https://github.com/Microsoft/microsoft-ui-xaml-specs/blob/master/docs/feature_proposal_process.md أضف عنوانًا لميزة أو اقتراح واجهة برمجة التطبيقات. من فضلك كن قصيرًا ووصفيًا

الاقتراح: ScrollViewer

ملخص

TL: د. قم بتوفير عنصر تحكم مرن وسهل الاستخدام والتمرير والتكبير / التصغير في XAML والذي لا يزال من الممكن الاستفادة منه عند استهداف الإصدارات ذات المستوى الأدنى من Win10.

يلعب عنصر تحكم ScrollViewer دورًا مهمًا في أي واجهة مستخدم نظرًا لمدى أهمية التمرير للتطبيقات وعناصر التحكم (النظام الأساسي وغير النظام الأساسي على حد سواء). يوفر عنصر التحكم إمكانات التحريك والتكبير جنبًا إلى جنب مع السياسات الافتراضية وتجربة المستخدم (على سبيل المثال ، أشرطة التمرير الواعية ، والتفاعل مع التركيز / لوحة المفاتيح ، وإمكانية الوصول ، والرسوم المتحركة الافتراضية للتمرير ، وما إلى ذلك). يجب أن يكون أيضًا مرنًا بدرجة كافية بحيث يمكن أن ينتقل من جعل سيناريوهات التطبيق اليومية سهلة إلى كونه مكونًا رئيسيًا في عناصر التحكم القائمة على التمرير وخدمة حالات الاستخدام المتقدمة للغاية. لا يوفر عنصر التحكم الحالي هذا المستوى من المرونة.

المنطق

يرجى وصف سبب إضافة الميزة إلى WinUI لجميع المطورين والمستخدمين. إذا أمكن ، يمكنك أيضًا وصف كيفية توافقها مع خارطة طريق WinUI الحالية والأولويات: https://github.com/Microsoft/microsoft-ui-xaml-specs/blob/master/docs/roadmap.md

يعد إحضار عنصر تحكم ScrollViewer إلى الريبو بطريقة متدرجة فوق واجهات برمجة التطبيقات العامة للنظام الأساسي الأساسي بمثابة نقطة انطلاق مهمة:

  1. تمكن من رفع المزيد من عناصر التحكم في الريبو (خفة الحركة المتزايدة) ،
  2. يمنح المطورين تحكمًا سهل الاستخدام يبرز مرونة قدرات النظام الأساسي ذات المستوى الأدنى جنبًا إلى جنب مع الاستفادة من خدمات إطار العمل ذات المستوى الأعلى (مثل إمكانية الوصول) ، و
  3. تمكن الميزات الأحدث المتعلقة بالتمرير في XAML لتضيء على الإصدارات السابقة من Win10.

تم تأليف عنصر التحكم الحالي في Win8 استنادًا إلى DirectManipulation APIs والتي 1) غير متاحة للاستخدام مباشرة داخل UWP ، 2) لا تسمح بمستوى التخصيص الذي توقعه المطورون لإنشاء تجارب تمرير فريدة ، و 3) يتم تجاوزها بواسطة واجهات برمجة تطبيقات InteractionTracker الأحدث في UWP.

لن يكون استخراج عنصر تحكم ScrollViewer الحالي كما هو بداية. يجب أن يكون عنصر التحكم بدلاً من ذلك إعادة تنفيذ مع سطح واجهة برمجة تطبيقات متطابق تقريبًا استنادًا إلى الإمكانات الأحدث (والمتاحة بالفعل) لـ InteractionTracker .

خطة عالية المستوى

سيظل ScrollViewer الموجود في _Windows_.UI.Xaml.Controls مساحة الاسم كما هو (بخلاف إصلاح الأخطاء الحرجة).

سيعيش ScrollViewer الجديد في مساحة الاسم _Microsoft_.UI.Xaml.Controls. ستكون واجهة برمجة التطبيقات الخاصة بها مطابقة في الغالب لإصدار _Windows_. سنقوم بإجراء تعديلات مستهدفة على واجهة برمجة تطبيقات عنصر التحكم حيث توجد فائدة واضحة (تبسيط سيناريو مشترك ، وإدخال إمكانات جديدة ، وما إلى ذلك).

بالاقتران مع ScrollViewer الجديد ، سنقدم نوعًا جديدًا ، Scroller ، والذي سيعيش في Microsoft.UI.Xaml.Controls._Primitives_ namespace. سيوفر Scroller الوظائف الأساسية للتمرير والتكبير في XAML بناءً على قدرات InteractionTracker .

سيكون الهدف الأولي لكلا الضابطين هو الحصول على الوظائف الأساسية لشحن الجودة لتكون جزءًا من الإصدار الرسمي التالي. ستظل واجهات برمجة التطبيقات غير النهائية في "معاينة" وستكون متاحة فقط كجزء من حزم ما قبل الإصدار.

-------------------- الأقسام التالية اختيارية عند تقديم فكرة أو اقتراح. جميع الأقسام مطلوبة قبل أن نقبل العلاقات العامة لإتقانها ، ولكنها ليست ضرورية لبدء المناقشة. ----------------------

المتطلبات الوظيفية


| # | ميزة | | الأولوية |
|: -: |: - | - |: -: |
| 1 | يوفر عنصر تحكم _غير مختوم _ والتحريك والتكبير / التصغير مع UX الافتراضي المطابق لـ ScrollViewer الحالي. || يجب |
| 2 | يوضح قدرات النظام الأساسي من خلال الاعتماد فقط على واجهات برمجة التطبيقات العامة التي تدعم النظام الأساسي. || يجب |
| 3 | يتكامل مع خدمات XAML على مستوى إطار العمل.
على سبيل المثال:
- يعرض بشكل صحيح مجالات تركيز النظام
- عرض العناصر المركزة تلقائيًا (لوحة المفاتيح ، لوحة الألعاب ، قارئات الشاشة)
- يشارك في تغييرات منفذ العرض الفعالة
- يدعم تثبيت التمرير || يجب |
| 4 | قادرة على أداء الرسوم المتحركة المبنية على المدخلات || يجب |
| 5 | يمكن استخدامه مع عناصر التحكم الحالية المعتمدة على التمرير الموجودة بالفعل في الريبو (مثل ParallaxView و RefreshContainer و SwipeControl). || يجب |
| 6 | قادرة على التحكم في المنحنى لتغييرات العرض بالقصور الذاتي (مثل التمرير أو التكبير المتحرك المخصص). || يجب |
| 7 | قادرة على تغيير العرض بناءً على تعويضات مطلقة أو نسبية (على سبيل المثال ، انتقل إلى نقطة اهتمام) || يجب |
| 8 | قادرة على تغيير طريقة العرض بناءً على نبضة / سرعة إضافية (على سبيل المثال ، التمرير السلس التلقائي أثناء السحب والإفلات أو التحديد المتعدد عبر مستطيل التحديد بالماوس) || يجب |
| 9 | قادرة على الكشف عن المسافة الزائدة ومقدارها || يجب |
| 10 | قادرة على مراقبة والتفاعل مع التغييرات في حالة التمرير || يجب |
| 11 | دعم للتمرير والتكبير / التصغير نقاط المفاجئة. || يجب |
| 12 | قادرة على استخدام عنصر تحكم "شريط التمرير" المخصص لقيادة التمرير (مثل شريط تمرير الخط الزمني للصور). || يجب |
| 13 | قادر على تكوين عنصر التحكم بسهولة لتجاهل أنواع معينة من المدخلات (على سبيل المثال ، الاستجابة للمس أو القلم ، ولكن تجاهل إدخال عجلة الماوس). || يجب |
| 14 | قادرة على حفظ واستعادة موضع التمرير (على سبيل المثال في قائمة افتراضية) || يجب |
| 15 | دعم الرؤوس / العناصر اللاصقة. || يجب |
| 16 | دعم التمرير السريع عندما يقوم المستخدم بإيماءات متكررة في تتابع سريع. || يجب |
| 17 | قم بتوفير تجربة مستخدم افتراضية لدعم النقر الأوسط بالماوس والتمرير . |mousewheel panning | يجب |
| 18 | دعم وضع النقر والتحريك عبر الماوس (على سبيل المثال ، نقل المحتوى داخل عارض PDF). |mouse hand cursor for panning | يجب |
| 19 | قادرة على استخدام عنصر تحكم مخصص لدفع التكبير (مثل شريط التكبير / التصغير). || يجب |
| 20 | قادرة على طباعة المحتوى الموجود في المنطقة القابلة للتمرير. || يجب |
| 21 | دعم إيماءات الدوران. || يمكن |
| 22 | قادرة على مزامنة منطقتين أو أكثر مع التمرير الخالي من الوميض والخدوش (على سبيل المثال ، سيناريو فرق النص). || يمكن |
| 23 | قادرة على تخصيص منحنى الرسوم المتحركة لتغييرات العرض المدفوعة بالمدخلات (أي تحديد سلوكيات الإصبع لأسفل مثل آبار الجاذبية). || يمكن |
| 24 | دعم إيماءة التمرير إلى أعلى أو أسفل . || يمكن |
| 25 | قادرة على تعطيل الإفراط . || يمكن |
| 26 | قادر على معالجة المحتوى بشكل انتقائي داخل ScrollViewer بناءً على خاصية ManipulationMode الخاصة بـ UIElement . || يمكن |
| 27 | قادرة على إيقاف القصور الذاتي و / أو الارتداد من القصور الذاتي. || يمكن |
| 28 | قادرة على تعطيل قطع المحتوى (أي CanContentRenderOutsideBounds ). || يمكن |
| 29 | قادر على تحديد سبب الإكمال في نهاية تغيير طريقة العرض. || يمكن |

المصطلح

  • _ Overpan_ هو عندما يحاول المستخدم
  • _Railing_ هو عندما يقوم بإغلاق الحركة على محور "مفضل" بناءً على اتجاه الإيماءة الأولية.
  • _Chaining_ هو عندما يكون هناك سطح
  • _Snap Points_ هي مواقع داخل المحتوى القابل للتمرير حيث سيتوقف إطار العرض في نهاية التمرير بالقصور الذاتي (أي تمرير متحرك بعد أن يرفع المستخدم إصبعه). نقاط Snap مطلوبة لعنصر تحكم مثل FlipView.
  • _Scroll anchoring_ هو المكان الذي ينتقل فيه إطار العرض تلقائيًا للحفاظ على الموضع النسبي للمحتوى المرئي. يمنع المستخدمين من التأثر بالتحولات المفاجئة في موضع المحتوى أو حجمه بسبب التخطيط (أي أن المستخدم يقرأ مقالة وبعد لحظات قليلة يقفز كل شيء لأسفل لأن صورة / إعلان في الجزء العلوي من المقالة تم تحميله أخيرًا) . يعد إرساء التمرير ضرورة لظاهرية واجهة المستخدم عند التعامل مع محتوى متغير الحجم.
  • _آبار الجاذبية_ هي مواقع داخل المحتوى القابل للتمرير والتي تؤثر على سلوك التمرير أثناء معالجة المستخدم للمحتوى (أي أن إصبع المستخدم لأسفل). على سبيل المثال ، يمكن استخدام آبار الجاذبية لتغيير الاحتكاك الملحوظ للتمرير حيث يبدو أن الحركة تتباطأ أو تتسارع بينما يقوم المستخدم بالتحريك أو التكبير.

أمثلة على الاستخدام

الرجاء تضمين مثال واحد أو أكثر يوضح كيفية استخدامك لهذه الميزة. يمكنك تضمين أمثلة التعليمات البرمجية أو لقطات الشاشة إذا كان ذلك يساعدك

مقدمة

بشكل افتراضي ، يدعم ScrollViewer التحريك عبر محتوياته عندما يكون حجم المحتوى أكبر من منفذ العرض الخاص به. يتم تحديد حجم المحتوى بواسطة نظام تخطيط XAML.

تهدف الأمثلة هنا إلى إبراز الاختلاف الرئيسي في واجهة برمجة التطبيقات بين ScrollViewer الحالي و ScrollViewer الجديد.

التمرير العمودي (لا فرق)

يتم تقييد عرض المحتوى تلقائيًا ليكون مطابقًا لإطار العرض. الارتفاع غير مقيد. إذا تجاوز ارتفاع منفذ العرض ، فيمكن للمستخدم التحريك عبر طرق الإدخال المختلفة.

<ScrollViewer Width="500" Height="400">
    <ItemsRepeater ItemsSource="{x:Bind ViewModel.Items}" ItemTemplate="{StaticResource MyTemplate}"/>
</ScrollViewer>

التمرير الأفقي

هذا خروج متعمد من ScrollViewer الحالي الذي تطلب سابقًا تغيير HorizontalScrollBarVisibility. لقد أربك العديد من المطورين.

<ScrollViewer Width="500" Height="400" ContentOrientation="Horizontal">
    <StackPanel Orientation="Horizontal">
        <!-- ... -->
    </StackPanel>
</ScrollViewer>

يتم تمكين التمرير الأفقي فقط عن طريق تعيين خاصية _ContentOrientation_ . يحدد القيود المستخدمة على المحتوى أثناء التخطيط. تشير قيمة Horizontal إلى أن المحتوى غير مقيد أفقيًا (مسموح بالحجم اللامتناهي) ومقيد رأسياً لمطابقة منفذ العرض. وبالمثل ، يشير Vertical (الافتراضي) إلى أنه غير مقيد رأسيًا ومقيّدًا أفقيًا.

تمرير صورة كبيرة

يشير اتجاه المحتوى لكل من _Both_ إلى أن المحتوى غير مقيد أفقيًا وعموديًا.

<ScrollViewer Width="500" Height="400" ContentOrientation="Both">
    <Image Source="Assets/LargeEiffelTower.png"/>
</ScrollViewer>

تغيير رؤية شريط التمرير

هذا المثال يخفي دائمًا كلا من أشرطة التمرير. لا يزال بإمكان المستخدم تحريك المحتوى في أي من الاتجاهين.

<ScrollViewer Width="500" Height="400"
              ContentOrientation="Both"
              HorizontalScrollBarVisibility="Hidden"
              VerticalScrollBarVisibility="Hidden">
    <Image Source="Assets/LargeEiffelTower.png"/>
</ScrollViewer>

إيقاف تشغيل الدعم المدمج لأنواع معينة من المدخلات

في هذا المثال ، يقوم أحد المطورين بإنشاء تطبيق قائم على لوحة الرسم يقوم بإجراء معالجة مخصصة على إدخال عجلة الماوس ويدعم تجربة تحديد lasso عبر Pen. يمكنه تكوين ScrollViewer لتجاهل تلك الأنواع من المدخلات مع الاستمرار في قبول أنواع أخرى مثل Touch.

<ScrollViewer IgnoredInputKind="MouseWheel,Pen"
              Width="500" Height="400"
              ContentOrientation="Both" >
    <SwapChainPanel x:Name="swapChainPanel" Width="40000" Height="40000">
        ...
    </SwapChainPanel>
</ScrollViewer>

تخصيص الرسوم المتحركة للتمرير الآلي

يستمع المطور إلى حدث ValueChanged في Slider ويقوم بتحريك VerticalOffset في ScrollViewer باستخدام مدة مخصصة على الرسوم المتحركة الافتراضية.

private void VerticalOffsetSlider_ValueChanged(
    object sender,
    RangeBaseValueChangedEventArgs e)
{
    double verticalOffsetDelta = GetOffsetDelta();
    TimeSpan animationDuration = GetCustomAnimationDuration();

    // Initiate the scroll and enqueue the ScrollInfo we'll use to identify related events
    ScrollInfo scrollInfo = _scrollViewer.ScrollBy(0.0, verticalOffsetDelta);
    _myScrollRequests.Add(new MyScrollRequest(scrollInfo, animationDuration));
}

// Listen to the ScrollViewer's ScrollAnimationStarting event and customize 
// the default animation
private void ScrollViewer_ScrollAnimationStarting(
    ScrollViewer scrollViewer,
    ScrollAnimationStartingEventArgs e)
{
    MyScrollRequest myScrollRequest = _myScrollRequests.FindRequest(e.ScrollInfo);
    e.Animation.Duration = myScrollRequest.AnimationDuration;
}

// Dequeue the ScrollInfo once the action completes
private void ScrollViewer_ScrollCompleted(
    ScrollViewer scrollViewer,
    ScrollCompletedEventArgs e)
{
    _myScrollRequests.RemoveRequest(e.ScrollInfo);
}

تصميم تفصيلي للميزة

يرجى تضمين أي تفاصيل مهمة عن التصميم. يمكن أن يشمل ذلك واحدًا أو أكثر من: - اقتراح واجهة برمجة التطبيقات (أي لغة مدعومة أو كود زائف جيد) - تصميم نماذج بالأحجام الطبيعية لتجربة مستخدم جديدة - تفاصيل حول توافق إمكانية الوصول لواجهة مستخدم جديدة - ملاحظات تنفيذ أخرى

التمرير ذو السياسة العالية والسياسة المنخفضة

Scroller (سياسة منخفضة)

إن Scroller عبارة عن كتلة بناء منخفضة المستوى خالية من الكروم توفر كل منطق التحريك والتكبير الأساسي. إنه يلف InteractionTracker منخفض السياسة للنظام الأساسي كعنصر ملائم لترميز XAML.
بطريقة حرفية للغاية ، يكون Scroller هو "منفذ العرض" لـ ScrollViewer ويحل محل ScrollContentPresenter. ومع ذلك ، فإن Scroller ، على عكس ScrollContentPresenter ، يقوم بأكثر من مجرد قص محتواه.

يوفر Scroller مرونة استخدام InteractionTracker مباشرة إلى جانب المزايا التالية:

  • دعم الوصول
  • صياغة سهلة للترميز وواجهة برمجة تطبيقات سهلة الاستخدام
  • التكامل مع نظام تخطيط XAML وقدرات المحاكاة الافتراضية

ScrollViewer (سياسة عالية)

يلتف ScrollViewer الجديد في Scroller ويعين خصائصه على القيم المشتركة. على سبيل المثال ، يقوم <ScrollViewer/> بتكوين Scroller الخاص به لدعم تفاعلات التمرير الأفقي والرأسي ، ولكنه يقيد عرض محتواه بحيث يبدو أن تجربة المستخدم الافتراضية هي التمرير الرأسي فقط (الحالة الشائعة).

يوفر ScrollViewer المزايا التالية عن استخدام Scroller:

  • تجربة المستخدم الافتراضية (مثل مؤشر التمرير وأشرطة التمرير الواعية للماوس ومنحنى الرسوم المتحركة الافتراضي)
  • لا يتم التعامل مع الدعم الافتراضي للإدخال المرتبط بواجهة المستخدم بواسطة Scroller / InteractionTracker (مثل لوحة المفاتيح و GamePad)
  • حركة التركيز الافتراضية لـ GamePad (الصفحة لأعلى / لأسفل وضبط التركيز تلقائيًا استجابةً للمشغلات)
  • الوعي الافتراضي بإعدادات نظام المستخدم (على سبيل المثال إخفاء أشرطة التمرير تلقائيًا في Windows)
  • (مستقبلاً) خيارات تكوين سهلة للنقاط المفاجئة
  • (في المستقبل) دعم لمزيد من أوضاع تحريك الماوس (على سبيل المثال ، انقر واسحب المحتوى بيد مفتوحة / قريبة ، وتحريك الماوس عبر عجلة الماوس / النقر على الزر الأوسط يظهر مؤشر "البوصلة")

أي واحد يستخدم؟

يجب أن يكون الخيار الافتراضي للتطبيقات والعديد من مؤلفي التحكم هو استخدام ScrollViewer. يوفر سهولة أكبر في الاستخدام وتجربة مستخدم افتراضية متوافقة مع النظام الأساسي. يكون Scroller مناسبًا عندما لا تكون UX / السياسات الافتراضية مطلوبة - على سبيل المثال ، إنشاء عنصر تحكم FlipView محسّن أو سطح تمرير خالٍ من الكروم.

واجهات برمجة تطبيقات ScrollViewer فقط

HorizontalScrollBarVisibility / VerticalScrollBarVisibility

القيمة الافتراضية لكل من أشرطة التمرير الأفقية والعمودية هي _Auto_. يتم إظهارها أو إخفاؤها تلقائيًا بناءً على ما إذا كان المحتوى أوسع / أطول من إطار العرض أم لا.

لن يكون خيار "معطل" موجودًا في خيارات التعداد المتاحة لـ ScrollViewer الجديد. بدلاً من ذلك ، فإن تكوين عنصر التحكم للاستجابة لتفاعلات المستخدم التي يتم عرضها أفقيًا أو رأسيًا سيعتمد فقط على خصائص _HorizontalScrollMode_ و _VerticalScrollMode_.

namespace Microsoft.UI.Xaml.Controls
{
    public enum ScrollBarVisibility
    {
        Auto = 0,    // Only visible when the ZoomFactor * content size > viewport
        Visible = 1, // Always visible
        Hidden = 2   // Always hidden
    }
}

في الصورة أسفل مؤشر الماوس فوق شريط التمرير العمودي. إنه الوحيد المرئي لأن المحتوى له نفس عرض إطار العرض.

عندما يكون المحتوى أكبر من منفذ العرض في كلا البعدين ، يمكن رؤية شريطي التمرير الواعي بالإضافة إلى الفاصل في الزاوية اليمنى السفلية.

واجهات برمجة تطبيقات التمرير فقط

HorizontalScrollController / VerticalScrollController

يمكن توصيل Scroller بـ "عنصر واجهة مستخدم" تفاعلي يتحكم في التمرير عن طريق تعيين _HorizontalScrollController_ و _VerticalScrollController_ إلى نوع يقوم بتنفيذ واجهة _IScrollController_. أشرطة التمرير هي أمثلة مألوفة لهذه الأدوات. يوفر ScrollViewer Scroller الخاص به مع اثنين من هذه الأدوات. على سبيل المثال ، يمكن للمطور إنشاء تطبيق IScrollController مخصص يعتمد على Composition.Visual لإدخال UI-thread المستقل.

_scroller.HorizontalScrollController = new Acme.Slider(orientation: Orientation.Horizontal);
_scroller.VerticalScrollController = new Acme.Slider(orientation: Orientation.Vertical);

حدود المستوى الأدنى من ScrollViewer / Scroller

يجب أن يحتوي إطار العمل على جميع الخطافات الضرورية المكشوفة لإنشاء عنصر تحكم تمرير مخصص اعتبارًا من تحديث Windows 10 April 2018. عند استهداف الإصدارات السابقة ، قد تكون هناك قيود:
| الإصدار | القيد | السبب |
|: -: |: - |: -: |
| تحديث Windows 10 Fall Creators (النسخة 16299) والإصدارات الأقدم | لن يتم عرض العناصر تلقائيًا عند تلقي التركيز. | حدث BringIntoViewRequested الخاص بـ UIElement غير متوفر |
| | لا يمكن لعنصر التحكم المشاركة في أحداث EffectiveViewportChanged. لن يتم اقتصاص مستطيل التركيز الذي يعرضه النظام على حدود منفذ العرض. | UIElement's RegisterAsScrollPort غير متوفر |

API المقترحة

ScrollViewer

ج #
فئة عامة Microsoft.UI.Xaml.Controls.ScrollViewer: التحكم
{
ScrollViewer () ،

// Default Value: non-null instance
Windows.UI.Composition.CompositionPropertySet ExpressionAnimationSources { get; }

/ *

  • خصائص التخطيط المركزي
    * /
    // القيمة الافتراضية: null
    محتوى UIElement {get؛ يضع؛ } ؛
// Default Value: Vertical
Microsoft.UI.Xaml.Controls.ContentOrientation ContentOrientation { get; set; };

// Default Value: 0.0
Double HorizontalOffset { get; };

// Default Value: 0.0
Double VerticalOffset { get; };

// Default Value: 1.0
Single ZoomFactor { get; };

// Default Value: 0.0
Double ExtentWidth { get; };

// Default Value: 0.0
Double ExtentHeight { get; };

// Default Value: 0.0
Double ViewportWidth { get; };

// Default Value: 0.0
Double ViewportHeight { get; };

// Default Value: 0.0
Double ScrollableWidth { get; };

// Default Value: 0.0
Double ScrollableHeight { get; };

// Default Value: Auto
M.UI.Xaml.Controls.ScrollBarVisibility HorizontalScrollBarVisibility {get;set;};

// Default Value: Auto
M.UI.Xaml.Controls.ScrollBarVisibility VerticalScrollBarVisibility {get;set;};

// Default Value: Collapsed
// Used for template binding the Visibility property of the horizontal
// ScrollBar in the control template
Visibility ComputedHorizontalScrollBarVisibility{ get; };

// Default Value: Collapsed
// Used for template binding the Visibility property of the vertical
// ScrollBar in the control template
Visibility ComputedVerticalScrollBarVisibility{ get; };

/ *

  • خصائص تتمحور حول تفاعل المستخدم
    * /
    // القيمة الافتراضية: ممكّن
    Microsoft.UI.Xaml.Controls.ScrollMode HorizontalScrollMode {get؛ يضع؛ } ؛
// Default Value: Enabled
Microsoft.UI.Xaml.Controls.ScrollMode VerticalScrollMode { get; set; };

// Default Value: Disabled
Microsoft.UI.Xaml.Controls.ZoomMode ZoomMode { get; set; };

// Default Value: All
Microsoft.UI.Xaml.Controls.InputKind IgnoredInputKind { get; set; };

// Default Value: Idle
Microsoft.UI.Xaml.Controls.InteractionState State { get; };

// Default Value: Auto
Microsoft.UI.Xaml.Controls.ChainingMode HorizontalScrollChainingMode { get; set; };

// Default Value: Auto
Microsoft.UI.Xaml.Controls.ChainingMode VerticalScrollChainingMode { get; set; };

// Default Value: True
boolean IsHorizontalRailEnabled { get; set; };

// Default Value: True
boolean IsVerticalRailEnabled { get; set; };

// Default Value: Auto
Microsoft.UI.Xaml.Controls.ChainingMode ZoomChainingMode { get; set; };

// Default Value: None
M.UI.Xaml.Controls.SnapPointsType HorizontalSnapPointsType { get; set; };

// Default Value: None
M.UI.Xaml.Controls.SnapPointsType VerticalSnapPointsType { get; set; };

// Default Value: Near
M.UI.Xaml.C.Primitives.SnapPointsAlignment HorizontalSnapPointsAlignment { g;s; };

// Default Value: Near
M.UI.Xaml.C.Primitives.SnapPointsAlignment VerticalSnapPointsAlignment { g;s; };

// Default Value: 0.95, 0.95
Windows.Foundation.Numerics.Vector2 ScrollInertiaDecayRate { get; set; }; 

// Default Value: 0.95
Single ZoomInertiaDecayRate { get; set; }; 

// Default Value: 0.1
Double MinZoomFactor { get; set; };

// Default Value: 10.0
Double MaxZoomFactor { get; set; };

// Default Value: 0.0
Double HorizontalAnchorRatio { get; set; };

// Default Value: 0.0
Double VerticalAnchorRatio { get; set; };

// Forwarded to inner Scroller’s IScrollAnchorProvider implementation
// Default Value: null
Windows.UI.Xaml.UIElement CurrentAnchor { get; };

/ *

  • أساليب
    * /
    // ينتقل بشكل غير متزامن إلى الإزاحات المحددة. يسمح بالرسوم المتحركة ،
    // يحترم نقاط المفاجئة. ترجع بنية ScrollInfo.
    Microsoft.UI.Xaml.Controls.ScrollInfo ScrollTo (
    مزدوج أفقي
    إزاحة رأسية مزدوجة) ؛
// Asynchronously scrolls to specified offsets with optional animation,
// with optional snap points respecting. Returns a ScrollInfo struct.
Microsoft.UI.Xaml.Controls.ScrollInfo ScrollTo(
    double horizontalOffset,
    double verticalOffset,
    Microsoft.UI.Xaml.Controls.ScrollOptions options);

// Asynchronously scrolls by the provided delta amount.
// Allows animation, respects snap points. Returns a ScrollInfo struct.
Microsoft.UI.Xaml.Controls.ScrollInfo ScrollBy(
    double horizontalOffsetDelta,
    double verticalOffsetDelta);

// Asynchronously scrolls by the provided delta amount with
// optional animation, with optional snap points respecting.
// Returns a ScrollInfo struct.
Microsoft.UI.Xaml.Controls.ScrollInfo ScrollBy(
    double horizontalOffsetDelta,
    double verticalOffsetDelta,
    Microsoft.UI.Xaml.Controls.ScrollOptions options);

// Asynchronously adds scrolling inertia. Returns a ScrollInfo struct.
Microsoft.UI.Xaml.Controls.ScrollInfo ScrollFrom(
    Vector2 offsetsVelocity,
    Nullable<Vector2> inertiaDecayRate);

// Asynchronously zooms to specified zoom factor. Allows animation
// (respects snap points in v2). Returns a ZoomInfo struct.
Microsoft.UI.Xaml.Controls.ZoomInfo ZoomTo(
    float zoomFactor,
    Nullable<Vector2> centerPoint);

// Asynchronously zooms to specified offsets with optional animation
// (with optional snap points respecting in v2). Returns a ZoomInfo struct.
Microsoft.UI.Xaml.Controls.ZoomInfo ZoomTo(
    float zoomFactor,
    Nullable<Vector2> centerPoint,
    Microsoft.UI.Xaml.Controls.ZoomOptions options);

// Asynchronously zooms by the provided delta amount. Allows animation
// (respects snap points in v2). Returns a ZoomInfo struct.
Microsoft.UI.Xaml.Controls.ZoomInfo ZoomBy(
    float zoomFactorDelta,
    Nullable<Vector2> centerPoint);

// Asynchronously zooms by the provided delta amount with optional animation
// (with optional snap points respecting in v2). Returns an ZoomInfo struct.
Microsoft.UI.Xaml.Controls.ZoomInfo ZoomBy(
    float zoomFactorDelta,
    Nullable<Vector2> centerPoint,
    Microsoft.UI.Xaml.Controls.ZoomOptions options);

// Asynchronously adds zooming inertia. Returns a ZoomInfo struct.
Microsoft.UI.Xaml.Controls.ZoomInfo ZoomFrom(
    float zoomFactorVelocity,
    Nullable<Vector2> centerPoint,
    Nullable<float> inertiaDecayRate);

/ *

  • إعادة التوجيه إلى تطبيق IScrollAnchorProvider الداخلي
    * /
    باطل RegisterAnchorCandidate (عنصر UIElement) ؛
    void UnregisterAnchorCandidate (عنصر UIElement) ؛

/ *

  • الأحداث
    * /
    // يتم رفعه عند أي من HorizontalOffset و VerticalOffset و ZoomFactor
    // تغيرت خاصية التبعية.
    حدث TypedEventHandlerViewChanged؛
// Raised when any of the ExtentWidth and ExtentHeight dependency property changed.
event TypedEventHandler<ScrollViewer, Object> ExtentChanged;

// Raised when the State dependency property changed.
event TypedEventHandler<ScrollViewer, Object> StateChanged;

// Raised when a ScrollTo or ScrollBy call triggers an animation.
// Allows customization of that animation.
event TypedEventHandler<ScrollViewer, Microsoft.UI.Xaml.Controls.ScrollAnimationStartingEventArgs>
    ScrollAnimationStarting;

// Raised when a ZoomTo or ZoomBy call triggers an animation.
// Allows customization of that animation.
event TypedEventHandler
    <ScrollViewer, Microsoft.UI.Xaml.Controls.ZoomAnimationStartingEventArgs>
    ZoomAnimationStarting;

// Raised at the end of a ScrollTo, ScrollBy, or ScrollFrom asynchronous
// operation. Provides the original ScrollInfo struct.
event TypedEventHandler
    <ScrollViewer, Microsoft.UI.Xaml.Controls.ScrollCompletedEventArgs>
    ScrollCompleted;

// Raised at the end of a ZoomTo, ZoomBy, or ZoomFrom asynchronous operation.
// Provides the original ZoomInfo struct.
event TypedEventHandler
    <ScrollViewer, Microsoft.UI.Xaml.Controls.ZoomCompletedEventArgs>
    ZoomCompleted;

// Raised at the beginning of a bring-into-view-request participation.
// Allows customization of that participation. 
event TypedEventHandler
    <ScrollViewer, Microsoft.UI.Xaml.Controls.BringingIntoViewEventArgs>
    BringingIntoView;

// Raised to allow the listener to pick an anchor element, when anchoring
// is turned on.
event TypedEventHandler
    <ScrollViewer, Microsoft.UI.Xaml.Controls.AnchorRequestedEventArgs>
    AnchorRequested;

/ *

  • خصائص التبعية
    * /
    static DependencyProperty ContentProperty {get؛ } ؛
    static DependencyProperty ContentOrientationProperty {get؛ } ؛
    static DependencyProperty ComputedHorizontalScrollBarVisibilityProperty {get؛ } ؛
    static DependencyProperty ComputedVerticalScrollBarVisibilityProperty {get؛ } ؛
    static DependencyProperty HorizontalScrollBarVisibilityProperty {get؛ } ؛
    ثابت DependencyProperty VerticalScrollBarVisibilityProperty {get؛ } ؛
static DependencyProperty IgnoredInputKindProperty { get; };
static DependencyProperty HorizontalScrollModeProperty { get; };
static DependencyProperty VerticalScrollModeProperty { get; };
static DependencyProperty ZoomModeProperty { get; };
static DependencyProperty HorizontalScrollChainingModeProperty {g};
static DependencyProperty VerticalScrollChainingModeProperty {g};
static DependencyProperty IsHorizontalRailEnabledProperty {g};
static DependencyProperty IsVerticalRailEnabledProperty {g};
static DependencyProperty ZoomChainingModeProperty { get; };
static DependencyProperty MinZoomFactorProperty { get; };
static DependencyProperty MaxZoomFactorProperty { get; };
static DependencyProperty HorizontalAnchorRatioProperty { get; };
static DependencyProperty VerticalAnchorRatioProperty { get; };

}
""

أسئلة مفتوحة

  • هل سيؤدي وجود خاصية ContentOrientation (أو واحدة باسم مختلف) التي تؤثر على كيفية تطبيق قيود التخطيط على المحتوى إلى جعل الأمور أكثر تعقيدًا أو سهولة؟
  • هل يجب فصل واجهات برمجة التطبيقات المتعلقة بالتكبير / التصغير إلى عنصر تحكم مشتق (مثل ZoomViewer) بحيث يكون ScrollViewer يتعلق بالتمرير بشكل صارم؟
Epic area-Scrolling feature proposal proposal-NewControl team-Controls

التعليق الأكثر فائدة

هذا صحيح. كان لدينا 3 مواقف في الاعتبار:

  1. لا يهمني ما هو منصبي الحالي. أريد التمرير / التكبير إلى وجهة معينة.
  2. يهمني ما هو موقعي الحالي وأريد التمرير / التكبير بمقدار معين بالنسبة لهذا الموضع.
  3. لا يهمني ما هي الوجهة النهائية. أريد فقط التمرير / التكبير من موقعي الحالي.

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

ال 61 كومينتر

في رأيي ، فإن الحاجة إلى وجود محتوى يمكن تمريره ومحتوى يمكن تكبيره مختلفة تمامًا. أفهم أنه عند تكبير المحتوى ، غالبًا ما يحتاج أيضًا إلى التمرير ، لكنني أشعر بالفضول إذا كان هناك أي اعتبار لعمل عناصر التحكم المنفصلة هذه؟ ربما مع عنصر تحكم قابل للزووم يمتد من عنصر التمرير.
اهتماماتي هي: 1) أصبح ScrollViewer معقدًا بشكل مفرط عن طريق إضافة وظائف ذات صلة بالتكبير / التصغير والتي لن يحتاجها معظم الأشخاص ؛ 2) ليس من الواضح لشخص يبحث عن عنصر تحكم لتكبير المحتوى أن ScrollViewer يدعم هذا.


بالإضافة إلى ذلك ، ضمن الاقتراح ، أود أن أرى القدرة على التمرير إلى عنصر معين داخل عارض التمرير. من الناحية النظرية ، يمكن للمطور القيام بذلك عن طريق قياس جميع العناصر قبله ثم التمرير إلى الإزاحة المناسبة ، ولكن قد يكون من الصعب القيام بذلك مع القوائم الافتراضية وهو (في رأيي) سيناريو شائع بدرجة كافية للعديد من التطبيقات ( والمطورين) من أن يكون هذا مدمجًا.
ضع في اعتبارك مكان إضافة عنصر إلى "قائمة" ويريد المطور التأكد من أن هذا العنصر مرئي. أو ضع في اعتبارك صفحة بها عرض رئيسي / تفصيلي حيث يتم فتح الصفحة بطريقة عنصر تفصيلي أسفل القائمة ، لكن المطور يريد التأكد من عرض العنصر المحدد في القائمة الرئيسية ، لذا فهي توفر سياقًا لما هو معروض في عرض التفاصيل.

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

شكراmrlacey. أستطيع أن أرى كيف ستكون وظيفة التكبير / التصغير أقل قابلية للاكتشاف في ScrollViewer الحالي بالإضافة إلى هذا الاقتراح. لقد أضفت هذا كسؤال مفتوح للمناقشة لأنه سيكون نقطة انطلاق أخرى من UWP ScrollViewer الحالي (ربما للأفضل؟).

تجعل المحاكاة الافتراضية الأشياء صعبة نظرًا لأن العنصر المحدد قد يحتاج أولاً إلى الإنشاء والتشغيل من خلال نظام التخطيط للحصول على موضع يمكنك التمرير إليه بعد ذلك. هذا هو السبب في أن بعض الضوابط في الماضي (مثل ListView) كان لها طريقة ScrollIntoView الخاصة بها والتي تتعامل مع ما سبق لتسهيل الأمر. هل هذا هو نوع الطريقة التي تتخيلها؟ بدلاً من ذلك ، يحتوي كل UIElement على طريقة StartBringIntoView يمكن استخدامها للتمرير بسهولة شديدة إلى عنصر ولديه عدد من الخيارات لتوفير تحكم دقيق في المكان الذي يهبط فيه في منفذ العرض عند عرضه. يعمل أسلوب StartBringIntoView حتى في السيناريوهات مع أسطح التمرير المتداخلة نظرًا لأنه يولد طلبًا يتصاعد حتى يستجيب كل عنصر تحكم تمرير. هذا هو ما يحدث بشكل أساسي عندما يتلقى عنصر تركيز لوحة المفاتيح / لوحة الألعاب / الراوي. بالطبع ، يتطلب الأمر أن يكون لديك أولاً UIElement والذي قد لا يكون في سيناريو ظاهري بدون طريقة لتشغيل عنصر بشكل صريح ليتم تحقيقه. هل سيكون من المفيد أن يكون لديك طريقة لتحريك تحقيق عنصر بشكل صريح؟ من بين الأشياء الأخرى التي يمكنك استخدامها بعد ذلك لتشغيل StartBringIntoView.

إعادة: الحفاظ على موضع عنصر ما عند إضافة / إزالة محتوى آخر أو تغيير حجمه ... أوافق تمامًا على أن عدم القيام بأي شيء ليس جيدًا بما يكفي. هذا هو بالضبط سبب وجود ميزة إرساء التمرير . :) إنها قدرة غير معروفة تم دمجها في الماضي في اللوحات الافتراضية لـ ListView / GridView. في الإصدارات الأخيرة ، كنا نبذل جهدًا واضحًا لفصل أشياء مثل هذه عن كونها متاحة فقط في ListView.

إذا كان من المقرر استكشاف فكرة ScrollViewer الموسعة ، فربما يمكن لفرق Fluent Design تقديم النصح لك حول التعامل مع اختلاف المنظر والعناصر ذات قيم z-deep التي تم تعيينها افتراضيًا.

عندما ينتقل XAML إلى تمثيلات ثلاثية الأبعاد لتطبيقات MR ، وعندما يصل العمق والظلال إلى 2D XAML - كيف يمكن للتمرير نقل العناصر ذات قيم العمق المختلفة ، وكيف يمكن أن تظهر الظلال أعلى أو خلف مؤشرات التمرير ، والمشكلات الأخرى التي قد تظهر في تجارب فريق XAML ثلاثية الأبعاد - يمكن دمجها في ما يمكن أن يصبح افتراضيًا جديدًا ، حيث تصبح مكتبة Windows UI ببطء الافتراضي الجديد.

في رأيي ، فإن الحاجة إلى وجود محتوى يمكن تمريره ومحتوى يمكن تكبيره مختلفة تمامًا.

باستثناء متصفحات الويب ، تطبيقات تصميم الرسومات ، تطبيقات المكتب ، عارضات PDF ..... أي شيء يعرض مستند محتوى.

اتفق مع mrlacey على أن عرض عنصر معين أمر مهم بالإضافة إلى تحديد مكان عرضه في العرض (أعلى ، وسط ، أسفل ، إلخ ...). يجب أيضًا أن تكون هناك طريقة لاكتشاف ما إذا كان العنصر معروضًا بالكامل أو مقطوعًا. بهذه الطريقة ، لا يتعين علي التمرير في العرض لإظهار عنصر إذا كنت أعرف أن العنصر معروض بالكامل أو حتى جزئيًا.

شكرا لكم جميعا! لقد جمعنا بعض أدوات القياس عن بُعد بخصوص الخصائص التي تميل التطبيقات إلى تعيينها في ترميزها ويظهر ZoomMode مباشرةً بعد * ScrollMode و * ScrollBarVisibility. في معظم الأوقات ، لا تغير التطبيقات أي خصائص. ما لاحظته عند تعيين خصائص ScrollMode و ScrollBarVisibility هو أنه غالبًا ما يتم تمكين التمرير الأفقي على المحتوى. يهدف إدخال خاصية ContentOrientation إلى تسهيل ذلك. بعد التمرير الأفقي ، يكون السيناريو التالي الأكثر شيوعًا هو التكبير / التصغير.

بدلاً من تقديم عنصر تحكم منفصل (مشتق) لمعالجة قابلية اكتشاف التكبير ، أعتقد أن التوثيق / العينات الصحيحة يمكن أن تكون أكثر فعالية.

ماذا عن إضافة سلوك أو سياق تعداد؟

ScrollViewer.ScrollBehaviour = ScrollBehaviour.Zoom;
ScrollViewer.ScrollBehaviour = ScrollBehaviour.Scroll;
ScrollViewer.ScrollBehaviour = ScrollBehaviour.ParallaxScroll;

ScrollViewer.ScrollBehaviour = ScrollBehaviour.Zoom; محير للغاية بالرغم من ذلك. أعتقد أن ZoomMode يجب أن يبقى كما هو.

ScrollViewer.ScrollBehaviour = ScrollBehaviour.Zoom; محير للغاية بالرغم من ذلك. أعتقد أن ZoomMode يجب أن يبقى كما هو.

ربما كان ينبغي أن أكون قد أعدت الاقتراح على أنه معالجة التعليقات التي تعتقد أنه يجب أن يكون هناك عنصر تحكم مشتق لتكبير المحتوى ، بدلاً من التمرير

بالنسبة لي ، من المنطقي أن يكون لديك وظيفة تكبير / تصغير مضمنة بـ ScrollViewer ، خاصة على الأجهزة التي تعمل باللمس. لا توجد حاليًا طريقة سهلة للقيام بالتحريك الحر / التكبير / التدوير على صورة / عنصر تحكم في UWP ، وقد تم طرح العديد من الأسئلة ذات الصلة على StackOverflow و GitHub (على سبيل المثال ، إضافة عنصر تحكم في المحتوى القابل للسحب ).

micahl ، أفترض مع التكبير و

دعم إيماءات الدوران

سيتم دعم هذا السيناريو محليًا في المستقبل؟

بالنسبة لي ، من المنطقي أن يكون لديك وظيفة تكبير / تصغير مضمنة بـ ScrollViewer ، خاصة على الأجهزة التي تعمل باللمس. لا توجد حاليًا طريقة سهلة للقيام بالتحريك الحر / التكبير / التدوير على صورة / عنصر تحكم في UWP ، وقد تم طرح العديد من الأسئلة ذات الصلة على StackOverflow و GitHub (على سبيل المثال ، إضافة عنصر تحكم في المحتوى القابل للسحب ).

إذا كانت هناك حاجة لمزيد من التحكم في التكبير والتمرير ...

ScrollViewer.ScrollBehaviour = ScrollBehaviour.ZoomAndScroll;

ولكن في الأجهزة التي تعمل باللمس ، من الطبيعي السماح بقرص الأصابع وانزلاقها. ومع ذلك ، فإن التكبير بدون لمس سيحتاج إلى ظهور أزرار [+] و [-]. أو ربما إذا كان التكبير فقط ، فسيتم تكبير وتصغير سحب الإبهام لشريط التمرير.

إذا نظرت إلى Microsoft Word UI ، فهناك عنصر تحكم Zoom في شريط الحالة. وأشرطة التمرير الخاصة بمنطقة المستند.

هل يدعم تكبير الماوس شيئًا يجب تضمينه في عنصر تحكم ScrollViewer الجديد؟ لذلك عندما يكون ZoomMode قيد التشغيل ، أو عندما تسمح خاصية السلوك بالتكبير / التصغير ، تظهر أزرار زائد وناقص؟

JustinXinLiu من المحتمل أن تتطلب إيماءات التدوير دعمًا من InteractionTracker (likuba).

mdtauk سيدعم ScrollViewer الجديد تكبير عجلة الماوس عبر Ctrl + عجلة الماوس على غرار ScrollViewer الحالي. ليس من الواضح بالنسبة لي ما إذا كان يجب أن يحتوي عنصر التحكم على زر زائد / ناقص افتراضي عند تمكين التكبير / التصغير. انطباعي الحالي هو أن أنواع التطبيقات التي عادةً ما تتيح التكبير (مثل تطبيق مستند المحتوى) تختار دمج هذه الأزرار في تجربة التطبيق الخاصة بهم بطرق متنوعة. على سبيل المثال ، a - / + في شريط الحالة الذي يتم فصله بواسطة شريط تمرير (مثل Office) أو مجرد - / + بسيط يظهر عموديًا أسفل الأوامر الأخرى (مثل الخرائط).

micahl لا أفهم سبب تسمية ScrollFrom بهذه الطريقة. أليس تمامًا مثل ScrollBy ولكن بمعامل سرعة؟

adrientetar هل تسأل لماذا لا يوجد حمل زائد آخر لـ ScrollBy مع مجموعة مختلفة من المعلمات بدلاً من تسميتها ScrollFrom؟

نعم أعتقد 😃 لكني أتخيل أن المفهوم الكامن وراء ScrollFrom هو التحرك في اتجاه بسرعة معينة؟ على عكس ScrollBy الذي هو مجرد الانتقال إلى نقطة معينة.

هذا صحيح. كان لدينا 3 مواقف في الاعتبار:

  1. لا يهمني ما هو منصبي الحالي. أريد التمرير / التكبير إلى وجهة معينة.
  2. يهمني ما هو موقعي الحالي وأريد التمرير / التكبير بمقدار معين بالنسبة لهذا الموضع.
  3. لا يهمني ما هي الوجهة النهائية. أريد فقط التمرير / التكبير من موقعي الحالي.

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

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

في عنصر تحكم ScrollViewer الحالي ، من الممكن الارتباط بخصائص ViewportWidth و ViewportHeight ، ولكن لا يبدو هذا ممكنًا حاليًا في عنصر التحكم ScrollViewer الجديد. هل سيضاف هذا؟

lhak ، ما الذي

micahl أنا متأكد من أنني استخدمت هذه القيم في الماضي أيضًا لبعض الحسابات. لست متأكدًا مما إذا كنت ملتزمًا بهم.

@ michael-hawker للتوضيح ، ستكون الخصائص متاحة على ScrollViewer. ومع ذلك ، في واجهة برمجة التطبيقات المقترحة ، يتم عرضها كخصائص عادية بدلاً من خصائص التبعية. ستكون هذه القيم نفسها متاحة كجزء من خاصية ExpressionAnimationSources للمواقف التي يقوم فيها شخص ما ببناء رسوم متحركة تعتمد على المدخلات بناءً على التركيب.

أستخدم حاليًا بعض التعليمات البرمجية المشابهة لما يلي في تطبيقي:

<ScrollViewer x:Name="outputScrollViewer">
  <Viewbox MaxWidth="{x:Bind outputScrollViewer.ViewportWidth, Mode=OneWay}" MaxHeight="{x:Bind outputScrollViewer.ViewportHeight, Mode=OneWay}">
    <TheXamlElement Width=X Height=Y/>
  </Viewbox>
</ScrollViewer>

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

lhak ، سيناريو جيد! التفكير بصوت عالٍ في كيفية استيعاب هذا السيناريو في الاقتراح الحالي ... أعتقد أنه يمكننا إضافة خيار آخر لخاصية ContentOrientation. الخيارات الحالية في الاقتراح:

  • بلا = لا يوجد اتجاه مفضل. امنح المحتوى الحجم المتاح غير المحدود في كلا الاتجاهين.
  • أفقي = امنح المحتوى حجمًا متاحًا غير محدود أفقيًا فقط وقصر الارتفاع على منفذ العرض أثناء التخطيط.
  • عمودي = تبديل الأفقي

الخيار الرابع هو تقييد كل من الطول والعرض أثناء التخطيط بحجم إطار العرض. في الوقت الحالي سأسمي هذا اتجاه "منفذ العرض" ، على الرغم من أن لدي ردود فعل متباينة حول تسميته على هذا النحو.
أعتقد على الأقل في حالة الصورة (الأكثر شيوعًا؟) أنها ستجعل Viewbox والارتباطات غير ضرورية لأن "الشيء الصحيح" يجب أن يحدث كجزء من عملية التخطيط.

<ScrollViewer ContentOrientation="Viewport">
  <Image Stretch="Uniform" .../>
</ScrollViewer>

لمزيد من المحتوى المعقد ، ستتمكن من لفه في Viewbox ولا يزال بإمكانك تخطي الروابط.

<ScrollViewer ContentOrientation="Viewport">
  <Viewbox>
    <TheXamlElement Width=X Height=Y/>
  </Viewbox>
</ScrollViewer>

micahl لديك سؤال آخر: أود تغيير معالجة عجلة الماوس في Scroller لجعل التكبير أسرع (زيادات أكبر) وإزالة الرسوم المتحركة السهلة. يبدو أنه لا توجد واجهة برمجة تطبيقات لتعديل تكبير العجلة ، فهل أحتاج للتعامل مع حدث عجلة الماوس يدويًا؟

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

إذا لم يفلح ذلك ، فيمكنك الرجوع لمحاولة التعامل مع الأمر بنفسك عن طريق تعيين IgnoredInputKind = "عجلة الماوس" ثم إما تصنيف Scroller لتجاوز OnPointerWheelChanged ، أو إضافة معالج حدث لحدث PointerWheelChanged في Scroller.

micahl شكرا! لست متأكدًا من السيناريو الذي قمت بمعايرة سلوك عجلة الماوس وفقًا له ، فأنا شخصياً أحب الطريقة التي تكون عليها على سبيل المثال في Adobe XD: هناك القليل من الرسوم المتحركة المتسارعة على ما يبدو ولكنها سريعة ولديها زيادات كبيرة في التكبير / التصغير. تبدو الرسوم المتحركة لتكبير عجلة الماوس Scroller بطيئة بعض الشيء ولديها زيادات صغيرة في التكبير / التصغير imo.

adrientetar ، ردود فعل جيدة. يمكننا النظر في تعديله.

أي نوع من المتغيرات التي تتحكم في الزيادات والقيم - يمكن تحويلها إلى خصائص قابلة للتجاوز

حق. يتمثل أحد التحديات التي تواجهنا هنا في أنه في الإصدار 1809 من Win10 وما بعده ، ترفع يد التحكم عن إدخال عجلة الماوس إلى InteractionTracker الأساسي للسماح بمعالجتها خارج UI-thread لحركة أكثر سلاسة. يجب أولاً كشف تلك الخصائص القابلة للتجاوز على المستوى الأدنى. بالنسبة لإصدارات Win10 قبل 1809 ، نضيف منطقًا لإدخال عجلة الماوس في عملية التحكم في مؤشر ترابط واجهة المستخدم.

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

لذا فإن سلوك التكبير الحالي يتم وضعه في InteractionTracker دون أي طريقة لتجاوزه؟ وأعتقد الآن أنه لا توجد طريقة لتغييره لأنه سيعطل التوافق مع الإصدارات السابقة 🤔 cclikuba

أعتقد أن هناك بعض الخيارات على InteractionTracker التي يمكن أن تساعد هنا 😊. على وجه التحديد ، قمنا ببناء ميزات مثل PointerWheelConfig و DeltaScaleModifier لتمكين هذه الأنواع من التخصيصات. سنقوم بالمزامنة ونرى ما إذا كان استخدام هذه العناصر داخل عنصر التحكم يمكن أن يؤدي إلى حدوث شيء ما هنا دون المشاكل / المخاطر التي ذكرتها أعلاه.

micahl لدي موقف مثير للاهتمام في مشروع أعمل عليه واضطررت إلى كتابة برنامج Scrollviewer الخاص بي لـ PoC - لكني أود أن أعرف ما إذا كان لديك أي خطط (أو إذا كان عنصر التحكم هذا يدعم هذا بالفعل) من أجل السيناريو التالي:
لنفترض أن لديك لوحة قماشية عملاقة ، 10000 × 5000 لتحريكها ، تقوم بتغليفها في ScrollViewer.
الآن على اللوحة القماشية لديك 2 InkCanvases (أو أكثر) وتريد الكتابة على كليهما (أو أكثر) ، بأصابع مختلفة أو بإصبع واحد ومؤشر ماوس واحد. كيف يمكنك تحقيق ذلك (أو حتى ممكن) بهذه السيطرة؟ :)
ما رأيته هو السلوك الافتراضي بمجرد أن تلمس أي شيء آخر أثناء الرسم على InkCanvas ، هذا InkCanvas المحدد يطلق "PointerLost" وهذا كل شيء - لا شيء آخر تفعله.
من الواضح أن برنامج Scrollviewer الخاص بي بعيد جدًا عن الكمال كما كتبته بنفسي - لذلك أتطلع لمعرفة ما إذا كان هذا ممكنًا باستخدام هذا التحكم؟

شكرا لك أيها الطيب !

مرحبًا stefangavrilasengage ، سيناريو مثير للاهتمام. :) من PoC الخاص بك ، ما هو السلوك المتوقع عندما ينزل إصبع على InkCanvas ثم يبدأ في التحرك؟ هل هو رسم أم مقلاة؟

مرحبًا هناك micahl - شكرًا لك على الرد! أفترض الآن أنك خمنت أنه شيء مثل تطبيق السبورة البيضاء الرقمية.
سأقدم الآن ما يحدث حاليًا:

  • ScrollViewer (افتراضي): الرسم بإصبع واحد على InkCanvas جيد. الإصبع الثاني يجعل أول لوحة InkCanvas تفقد الإدخال.
  • ScrollViewerEx (عنصر تحكم مخصص): استخدم العديد من الأصابع وأكبر عدد من InkCanvases للرسم وهو يعمل.

هل هذا يساعد؟ :)
شكرا لك !

stefangavrilasengage كنت أسأل ما الذي يزيل الغموض بين ما إذا كانت إيماءات اللمسة الواحدة (السلوك الافتراضي لـ ScrollViewer) أو ترسم الحبر. هناك صراع متأصل هناك. كيف تحلها؟ تتطلب إصبعين للتمرير مثل الخريطة؟ استخدم زر التحرير للدخول / الخروج من وضع التحرير؟ إلخ...

micahl اعتذاري - نسيت أن أذكر كيف تمكنت من حل النزاع.
الكائنات التي لدينا على القماش لها حبرها داخل حاوية Win2D. فقط إذا قمت بإدخال وضع تحرير لكل كائن ، فسيتم تقديم InkCanvas في الأعلى للتحرير (مع تجفيف مخصص).
لذلك في موقفي (لست متأكدًا مما إذا كان هذا ينطبق على أي شخص آخر) ، إذا كان لديك InkCanvas نشط "قابل للرسم" ، فلا شيء يجب أن يصل إلى ScrollViewer.
سأكون فضوليًا لمعرفة حالة استخدام حيث تعتقد أن هذا لا ينطبق ، إن وجد؟

شكرا !

من الصعب تصديق أن هذه هي المرة الأولى التي نخلط فيها أنا و

من الصعب تصديق أن هذه هي المرة الأولى التي نخلط فيها أنا و

اسف بشأن ذلك ! تم تحريره!

micahgodbolt قد لا يكون الأخير. ؛)
تضمين التغريدة هذا يجيب على سؤالي. لقد لاحظت أن تبديل ScrollViewer بشيء آخر مثل Border حيث أن أصل لوحة Canvas التي تحتوي على عناصر تحكم InkCanvas متعددة لا يواجه نفس المشكلة. لذلك ، لقد تواصلت مع بعض الأشخاص داخليًا لفهم ما قد يتسبب في تعطل وظيفة الإدخال المتعدد / متعدد InkCanvas عندما يحدث داخل ScrollViewer.

stefangavrilasengage ، فإن معرفة سبب عدم

micahl لدي مشكلة مع Scroller حيث يؤدي التمرير والتكبير / التصغير حول المحتوى الخاص بي في OnControlLoaded إلى وضعني في موضع خاطئ. إذا قمت بالتمرير فقط ، ينتهي بي الأمر في الموضع الصحيح ، ولكن إذا قمت بالتكبير مباشرة بعد التمرير ، فأنا في وضع إيقاف التشغيل تمامًا ، على الرغم من أنني حددت centerPoint = فارغًا ، لذلك يتم تعيينه افتراضيًا على مركز منفذ العرض (من النظر إلى الكود لأنه يوجد لا توجد وثائق بعد AFaict). مع هذا الرمز .

شكرًا لتجربة الأشياء ،adrientetar! دعونا نحافظ على تركيز هذا الموضوع على الاقتراح. هل يمكنك فتح مشكلة منفصلة لما تراه؟ اعتمادًا على المكان الذي نتوصل إليه في تلك المناقشة ، قد نرغب في العودة إلى هذا الموضوع لمناقشة ما إذا كان يستدعي إجراء تغييرات على الاقتراح.

micahl لماذا يكون للأحداث ExtentChanged / StateChanged / ViewChanged كائنًا كحجة وليس على سبيل المثال ، StateChangedEventArgs مع أحد أعضاء الدولة؟ بالنظر إلى أن InteractionTracker يعمل على سلسلة رسائل مختلفة ، أليس نمط تمرير الرسالة (حدث مع وسيطة) مفضلًا للاستعلام عن خاصية التحكم في معالج الحدث؟

https://github.com/XeorgeXeorge/Extended-Image-Viewer

ليس بالأمر الكبير ، ولكن الجزء الأول من هذا الريبو يعرض كيفية تنفيذ التكبير حتى عندما تكون أشرطة التمرير الأفقية / الرأسية مقفلة (معطلة) ،

بكلمات أبسط:
يسمح بالتحريك على محتوى مكبّر مع الاستمرار في فرض الملاءمة لـ
منفذ عرض رأسي / أفقي فعال.

في وقت نشر هذا ، من الضروري تمكين خاصية HorizontalScrollbarVisibility في ScrollViewer من أجل الحصول فعليًا على عملية Zoom وظيفية ، وعلى الرغم من أنه قد تكون هناك طرق أفضل للتغلب على هذا ، أعتقد أن حل scrollViewer المزدوج الذي ألغيت معًا قد يكون كافيًا يكفي.

micahl أرى أن Scroller لا يرسل أحداث StateChanged عند إجراء تكبير غير متحرك ، فهل هذا حسب التصميم؟
أقوم بضبط مقياس CanvasVirtualControl الخاص بي عندما يصبح Scroller خاملاً ، كما اقترحت في https://github.com/microsoft/microsoft-ui-xaml/issues/541#issuecomment -488749469 ، بحيث لا ينتهي الأمر بتنقيط عنصر التحكم كبير جدًا أجزاء من اللوحة القماشية بالنسبة إلى عامل التكبير / التصغير. ولكن مع التكبير غير المتحرك ، أحتاج إلى القيام بذلك في الوقت الذي أسمي فيه طريقة ZoomTo ، على الرغم من أن تغيير التكبير / التصغير لم يتحقق (AFAICT).

adrientetar ، هناك بعض النفقات العامة لإنشاء

نعم ، التصميم الحالي هو أنه في التكبير غير المتحرك ، تستدعي برمجيًا حالة StateChanged لا تنطلق. سيتم رفع الحدث ZoomCompleted و ScrollCompleted استجابة للتغييرات البرمجية. IIRC لا يتم تشغيلها بواسطة تغييرات من المستخدم. يمكنك استخدام واحد من هؤلاء ، ربما بالاشتراك مع StateChanged. كما لمعلوماتك ، يتم رفع حدث ViewChanged في أي وقت يتغير فيه العرض (مستخدم أو برمجي) مما يجعله مسار رمز حساس للغاية وليس ما تريد استخدامه.

ما زلنا نستمع إلى التعليقات ، لذا إذا بدت الأمور غير واضحة ، فأخبرنا بذلك.

نعم ، التصميم الحالي هو أنه في التكبير غير المتحرك ، تستدعي برمجيًا حالة StateChanged لا تنطلق.

آه حسنًا ، فهمت الآن. ربما يمكن إطلاق الحدث دائمًا ويحتوي على معلمة أصل ، مثل SetFocus ، ولكن ربما يكون هناك بعض الجهد للقيام بذلك.

سيتم رفع الحدث ZoomCompleted و ScrollCompleted استجابة للتغييرات البرمجية. IIRC لا يتم تشغيلها بواسطة تغييرات من المستخدم.

حسنًا ، بالنسبة لحالة الاستخدام الخاصة بي ، يجب أن أتعامل مع ZoomCompleted و StateChanged iff State == Idle ، اعتمادًا على ما إذا كان التغيير برمجيًا أم لا. أليس هذا غريب؟ أعني ، أن يكون لديك أحداث مختلفة بأسماء مختلفة لنفس الشيء يؤدي فقط بطريقة مختلفة 🤔

أجرينا محادثة قصيرة مع

كانت الفكرة التي تمت مناقشتها هي أنه عندما يكون هناك تغيير في موضع التمرير / التكبير / التصغير على وشك الخدمة (سواء كان ذلك من قِبل المستخدم أو بشكل برمجي) ، فسنقوم برفع حدث StateChanged والإبلاغ عن الحالة الحالية كـ Transitioning. إليك ما سيبدو عليه التسلسل للتمرير الآلي (متحرك وليس متحركًا):

// طلب برمجي ، متحرك
myScrollInfo = ScrollTo (100، animate = true) ؛
// قليل من القراد
رفع StateChanged (Scroller.State == Transitioning)
// قليل من القراد
رفع StateChanged (Scroller.State == Animating)
// العديد من القراد
رفع StateChanged (Scroller.State == Idling)

// طلب آلي ، بدون رسوم متحركة
myScrollInfo = ScrollTo (100، animate = false) ؛
// قليل من القراد
رفع StateChanged (Scroller.State == Transitioning)
// قليل من القراد
رفع StateChanged (Scroller.State == Idling)

ربما نرغب في إعادة تسمية InteractionState enum إلى شيء مثل ScrollState لأنه يمثل أكثر من مجرد التفاعلات.

enum ScrollState
{
    Idling = 0,
    Transitioning = 1,
    Interacting = 2,
    Inertial = 3,
    Animating = 4,
};

micahl نعم ، هذا يشبه إلى حد كبير ما أتوقعه! يمكن للشخص الذي يريد التعامل مع التغييرات المتحركة فقط اعتراض حالة الرسوم المتحركة. بالنسبة للأسماء ، سأبقي Idle ليس Idling ("Scroller is idle" / "Scroller is animated") ، الانتقال → Stirring؟ (الانتقال محير للغاية ، أفضل أن ننقل أنه في بداية الحركة لذا قد يعمل التحريك imo

جعلني التحريك في البداية أفكر في المزج. :) سترغب مراجعة واجهة برمجة التطبيقات في التأثير عندما ننتهي من الأسماء ونميل إلى البحث عن سابقة. من الجيد دائمًا أن يكون لديك بعض الخيارات. قد تكون البدائل الأخرى غير معروفة أو معلقة. هناك سابقة في واجهات برمجة التطبيقات الحالية لكل من تلك الموجودة مع Idle مما يعني أننا ربما لا نفعل الخمول.

رائع رائع. في انتظار sgtm ، يعد imo Unknown أكثر إرباكًا من الانتقال.

micahl - يتضمن المتطلب الوظيفي رقم 3 هذه النقطة الفرعية:

يشارك في تغييرات منفذ العرض الفعالة (يجب)

تشير هذه النقطة الفرعية إلى الحدث الموجود مسبقًا FrameworkElement.EffectiveViewportChanged . هل هذه النقطة الفرعية كافية للقول (بشكل غير مباشر) أن التحميل الجزئي غير

  • تتطلب مهمة العرض هذه (عند نسبة تكبير / تصغير عالية) ما يقرب من 3 .. 20 ثانية ، اعتمادًا على تعقيد المستند (كمية عناصر المتجه ، التأثيرات ، إلخ) ، حجم المستند ، ونسبة التكبير / التصغير. هذا التأخير أكبر من أن يقبله المستخدمون.
  • يمكن أن تستهلك الصورة المقدمة (صورة نقطية) لصفحة PDF بأكملها مئات الميجابايت من ذاكرة الوصول العشوائي عندما تكون نسبة التكبير / التصغير عالية ، لأنها تعادل العرض بدقة عالية جدًا لكل بوصة.

يعرض MS Edge أجزاء من صفحة PDF المكبرة عند الطلب ، مما يعني أنه عندما يقوم المستخدم بتمرير هذه الأجزاء للعرض. تتجنب هذه التقنية التأخير الطويل قبل عرض الصفحة. أقترح أن المتطلبات الوظيفية تشير صراحةً إلى هذا السيناريو ، ولكن أيضًا مع دعم غير مباشر لـ async Task . عندما يتم تمرير جزء غير معروض (أو غير متوفر على الفور) إلى العرض ، يمكن لـ ScrollViewer ملء هذه المساحة مؤقتًا باستخدام Brush للتكوين ثم تشغيل حدث ، ويمكن لمعالج الحدث بدء async Task لتقديم (أو استرداد / تحميل) الجزء. في وقت لاحق ، عندما يكتمل Task ، يتم عرض الجزء الذي تم عرضه / استرداده / تحميله في ScrollViewer ، مما يغطي المساحة التي تم ملؤها مؤقتًا بـ Brush .

لا تتعلق هذه المشكلة فقط بالتكلفة العالية للتصيير بسرعة عالية. كما أنها قابلة للتطبيق على المحتوى الذي يتم استرداده عند الطلب. على سبيل المثال ، تخيل خريطة أو صورة قمر صناعي معروضة في ScrollViewer. يتم تنزيل أجزاء من الخريطة من الخادم فقط عندما يقوم المستخدم بتمريرها للعرض.

هل يجب فصل واجهات برمجة التطبيقات المتعلقة بالتكبير / التصغير إلى عنصر تحكم مشتق (مثل ZoomViewer) بحيث يكون ScrollViewer يتعلق بالتمرير بشكل صارم؟

على الرغم من أنني أقدر كثيرًا إضافة ScrollViewer.ZoomFactor ، إلا أنني فوجئت برؤيتها تمت إضافتها مباشرة إلى ScrollViewer. افترضت أنه سيكون من الأسهل والأكثر موثوقية وضع التكبير في فئة منفصلة (وليس بالضرورة فئة مشتقة). 3 طرق ممكنة على الأقل:

  1. فئة تسمى ربما ZoomViewer لا ترث ScrollViewer ، لكنها تستخدم مثيل ScrollViewer كعنصر فرعي (في ControlTemplate ).
  2. فئة تسمى ربما ZoomableScrollViewer ترث ScrollViewer .
  3. دعم التكبير مباشرة في حدود ScrollViewer ، إذا لم يكن الأمر معقدًا أو فوضويًا بشكل مفرط.

17 قم بتوفير UX الافتراضي لدعم النقر الأوسط بالماوس والتمرير. (يجب)
18 دعم وضع النقر والتحريك عبر الماوس (على سبيل المثال ، نقل المحتوى داخل عارض PDF). (يجب)

أقترح التفكير في إزالة الدعم لـ 17 ، لأن 18 يعمل بشكل أفضل بكثير من 17 ، وبالكاد يستخدم أي شخص 17 في الممارسة. من المسلم به أنني قد أفكر في أن 17 تعني شيئًا آخر غير المعنى المقصود (وصف 17 هو جملة واحدة فقط ولست متأكدًا بنسبة 100٪ أنه يعني ما أعتقد أنه يعني). أليس صحيحًا أن نقول إن 18 سهل الاستخدام للغاية وسهل الاستخدام ، في حين أن 17 أمر محرج يكافح الجميع لاستخدامه ويتجنب استخدامه؟
(تتغير هذه المشكلة إذا كانت هناك حاجة إلى 17 لأسباب تتعلق بإمكانية الوصول ، ولكن حتى الآن لم أسمع أي شخص يقول إن 17 مشكلة تتعلق بإمكانية الوصول.)

4 قادرة على أداء الرسوم المتحركة التي تحركها المدخلات

الرقم 4 هو مسألة متعلقة بإمكانية الوصول. أود أن أطلب من ScrollViewer (وجميع عناصر التحكم الأخرى في WinUI) احترام إعدادات الوصول:

Windows 10 -> ابدأ -> الإعدادات -> سهولة الوصول -> العرض -> إظهار الرسوم المتحركة في Windows (تشغيل أو إيقاف).

لسوء الحظ ، على مر السنين ، لاحظت العديد من الأمثلة حيث تتجاهل تطبيقات Microsoft إعدادات الوصول إلى Windows. تم إيقاف تشغيل الرسوم المتحركة ولكن تطبيقات Microsoft تعرض الرسوم المتحركة على أي حال. يتسبب هذا في صعوبات حقيقية للمستخدمين الذين يعتمدون على إعدادات الوصول هذه. لا يتمتع كل شخص بالقدرة على الاستمتاع بالرسوم المتحركة دون التعرض لآثار جانبية سلبية. قد يجد المستخدمون الذين لا يواجهون أي صعوبات في عرض الرسوم المتحركة وما إلى ذلك صعوبة في فهم أهمية إعدادات إمكانية الوصول في Windows.

مرحبًا verelpode ، predavid ستقود العمل حول ScrollViewer الجديد لذا سأحترمها.

17 قم بتوفير UX الافتراضي لدعم النقر الأوسط بالماوس والتمرير. (يجب)
18 دعم وضع النقر والتحريك عبر الماوس (على سبيل المثال ، نقل المحتوى داخل عارض PDF). (يجب)

أقترح التفكير في إزالة الدعم لـ 17 ، لأن 18 يعمل بشكل أفضل بكثير من 17 ، وبالكاد يستخدم أي شخص 17 في الممارسة. من المسلم به أنني قد أفكر في أن 17 تعني شيئًا آخر غير المعنى المقصود (وصف 17 هو جملة واحدة فقط ولست متأكدًا بنسبة 100٪ أنه يعني ما أعتقد أنه يعني). أليس صحيحًا أن نقول إن 18 سهل الاستخدام للغاية وسهل الاستخدام ، في حين أن 17 أمر محرج يكافح الجميع لاستخدامه ويتجنب استخدامه؟
(تتغير هذه المشكلة إذا كانت هناك حاجة إلى 17 لأسباب تتعلق بإمكانية الوصول ، ولكن حتى الآن لم أسمع أي شخص يقول إن 17 مشكلة تتعلق بإمكانية الوصول.)

verelpode أعتقد أنك تفهم 17 بشكل صحيح وأوافق على أن 18 أكثر أهمية وعادة ما تكون أكثر سهولة من 17. ولكن يمكن أن تكون هناك سيناريوهات حيث يتم استخدام "النقر بالزر الأيسر والسحب" بالفعل لأغراض أخرى ، مثل التحديد أو السحب + الإفلات . بالنسبة لمثل هذه السيناريوهات ، سيكون من الجيد أن يتمكن التطبيق من تمكين التمرير عبر النقر الأوسط (17).

أنا شخصياً أستخدم النقر الأوسط للتمرير في المتصفحات من وقت لآخر ، حيث يؤدي النقر بزر الماوس الأيسر + السحب إما إلى تحديد النص أو سحب + إسقاط الصور. سيكون متصفح UWP معطلاً 18 وتمكين 17. يجب أن يكون كلاهما مشتركًا عبر خصائص منفصلة.

تضمين التغريدة

أنا شخصياً أستخدم النقر الأوسط للتمرير في المتصفحات من وقت لآخر ، حيث يؤدي النقر بزر الماوس الأيسر + السحب إما إلى تحديد النص أو سحب + إسقاط الصور.

النقطة الجيدة هي الحاجة إلى تجنب التسبب في توقف اختيار النص وما إلى ذلك عن العمل. ما رأيك في هذا الحل المحتمل: اجعل النقر الأوسط يبدأ في وضع التحريك المستند إلى الماوس (18) بدلاً من بدء وضع 17 المحرج.

عندما ألقي نظرة على ما تفعله التطبيقات الأخرى ، تسمح لك بعض التطبيقات ببدء التحريك المستند إلى الماوس عن طريق الضغط باستمرار على مفتاح المسافة أثناء النقر بزر الماوس الأيسر في منطقة المحتوى القابلة للتمرير. يسمح هذا الحل بالنقر بزر الماوس الأيسر للعمل بشكل طبيعي داخل منطقة المحتوى القابلة للتمرير لأن وضع التحريك يبدأ فقط عبر مفتاح المسافة + النقر. أجد التحريك عبر مفتاح المسافة + النقر مريحًا جدًا ومريحًا وسريعًا.

ومع ذلك ، فإن حل spacebar + click أسهل في التنفيذ في التطبيقات التي لا تحتاج إلى عرض أي مربعات نصية قابلة للتحرير داخل منطقة المحتوى القابلة للتمرير. إذا كانت المربعات النصية القابلة للتحرير موجودة في منطقة المحتوى القابلة للتمرير ، فستكون هناك مشكلة في أن ميزة التحريك تجعل المستخدمين غير قادرين على كتابة مسافات في مربعات النص. لذلك ، كما قلت ، يجب تفعيل هذه الميزة عبر أحد العقارات. بدلاً من ذلك ، لا تستخدم مفتاح المسافة ، وبدلاً من ذلك ، اجعل النقر الأوسط يبدأ في وضع التحريك المستند إلى الماوس (18) ، وهذا يلغي مشكلة عدم قدرة المستخدمين على كتابة مسافات في مربعات النص.

تضمين التغريدة
مع جميع المتصفحات وأيضًا مجموعة من التطبيقات الأخرى (Word ، Adobe Reader ، Outlook ، ...) التي تدعم الوضع 17 ، ما زلت أعتقد أنه يجب تنفيذ ذلك. فقط لأنك تجده محرجًا شخصيًا لا يعني أنه غير مفيد للآخرين. يجب أن يكون كلا الوضعين قابلين للاشتراك بالطبع ، ثم يمكن للمطورين تحديد ما يجب استخدامه في تطبيقهم. سيسمح هذا أيضًا بسلوك spacebar + click ، ​​إذا كان ذلك منطقيًا لأحد التطبيقات: قم بتمكين الوضع 18 على مفتاح المسافة لأسفل ، وقم بتعطيله مرة أخرى على مفتاح المسافة لأعلى.

lukasf - حسنًا ، يبدو جيدًا. اعتقدت أنك تقصد أنه إذا لم يمنع وضع التحريك (18) تحديد النص أو سحب + إسقاط الصور وما إلى ذلك ، فستتوقف عن استخدام الوضع 17 والتبديل إلى 18 ، ولكن الآن أرى أن تفضيلك هو في الواقع لكلا الوضعين كن داعما.

شكرًا لك على ملاحظاتك verelpode و lukasf ، أنا أتفق معك في أننا لنسميها 17 = سرعة ثابتة تعتمد على الماوس وتحريكها و 18 = بالغسل على أساس الماوس.

لقد أرسلت للتو PR https://github.com/microsoft/microsoft-ui-xaml/pull/1472 لإضافة بعض الأعمال الاستقصائية التي قمت بها. أردت أن أرى مدى قربي من دعم كل من 17 و 18 باستخدام Scroller اليوم.

سارت الأمور على ما يرام بالنسبة لـ 18 = التحريك المستند إلى الماوس ، على الرغم من أن الحل مرتبط بواجهة مستخدم بنسبة 100٪ ، على عكس التجارب القائمة على اللمس أو التي تعتمد على عجلة الماوس. لقد استخدمت طريقة ScrollTo أثناء الاستماع إلى حدث PointerMoved الخاص بالماوس. في النهاية ، نرغب في أن يتعامل مكون InteractionTracker الأساسي مع حركات الماوس كما هو الحال مع حركات الأصابع.

الأمور أكثر تعقيدًا بالنسبة لـ 17 = تحريك السرعة الثابتة المستند إلى الماوس (تجربة لا أحبها شخصيًا). النموذج الأولي بعيد كل البعد عن المثالية ولم أحاول معالجة جميع القضايا ، ولكن هناك قضيتان على وجه الخصوص مقلقة:

  • أثناء تحريك السرعة الثابتة (أي 0-speed-decay panning) ، لا أعتقد أن هناك طريقة باستخدام Scroller الحالي لإيقاف الحركة دون القفز إلى موضع أقدم (باستخدام ScrollBy (0 ، 0)) . ليس من الممكن بشكل موثوق معرفة المدى الذي تقدم فيه مؤشر ترابط التكوين أمام مؤشر ترابط واجهة المستخدم. لذلك ستكون هناك حاجة إلى بعض واجهة برمجة تطبيقات Scroller العامة الجديدة لإيقاف السرعة بطريقة خالية من الأخطاء.
  • لم أتمكن من الحفاظ على التقاط الماوس بعد حدث PointerReleased الخاص بالماوس. يبدو أن ميزة إطار عمل Xaml الجديدة ستكون مطلوبة لتحقيق ذلك.
    على أي حال ، قد تكون هذه حالة أخرى حيث نرغب في InteractionTracker الأساسي أن يتعامل مع بعض التجربة مباشرة.
    سأضع هذه الأمور في الاعتبار بالتأكيد عند مناقشة ميزات Scroller / InteractionTracker المستقبلية.

تضمين التغريدة

سارت الأمور بشكل جيد بالنسبة لـ 18 = التحريك باستخدام الماوس ، ... ...
الأمور أكثر تعقيدًا بالنسبة لـ 17 = تحريك السرعة الثابتة المستند إلى الماوس (تجربة لا أحبها شخصيًا).

نتائج مثيرة للاهتمام! في هذه الحالة ، مع الأخذ في الاعتبار الصعوبات مع 17 = سرعة ثابتة ، وبالنظر إلى أنه يمكن تنفيذ 18 بطريقة لا تمنع الاستخدام العادي للنقرة اليسرى ، فأنا في رأيي الشخصي أعتقد أنه من المحتمل أن يتم تحديث الاقتراح إلى التخلي عن 17 ودعم 18 بدلاً من ذلك ، لكن من المسلم به أنني لا أعرف عدد المستخدمين الذين سيشتكون إذا تم التخلي عن 17 = السرعة الثابتة.

شكرًا لك RBrid على هذه التحقيقات. من الرائع سماع أن الوضع 18 يعمل بالفعل! أوافق على أنه يجب التعامل معه بشكل مثالي بواسطة InteractionTracker ، للسماح بالتشغيل السلس حتى أثناء تحميل مؤشر ترابط واجهة المستخدم.

verelpode تم تعيين كلا الوضعين على "should". لذلك ، إذا كانت الجهود عالية جدًا لتحقيق الوضع 17 ، فيمكن تركها (وربما إضافتها لاحقًا ، إذا لزم الأمر). لكن ربما يجد شخص ما طريقة لإدراك ذلك دون الكثير من التغييرات.

آمل أن يكون لدى ScrollViewer الجديد القدرة على تعطيل أو تخصيص Zoom باستخدام مفتاح "Ctrl".

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات