سؤال

حسنًا ، لقد اكتشفت كيفية الحصول على شبكتي من عناصر واجهة المستخدم للتكبير ، باستخدام LayoutTransform و ScaletRansform. ما لا أفهمه هو كيف يمكنني الحصول على وجهة نظري للرد على Ctrl+Mousewheelup Down للقيام بذلك ، وكيفية احتواء الكود في نمط MVVM.

كانت فكرتي الأولى هي تخزين Zoomfactor كخاصية ، وربط أمر لضبطه.

كنت أنظر إلى شيء مثل:

<UserControl.InputBindings>
 <MouseBinding Command="{Binding ZoomGrid}" Gesture="Control+WheelClick"/>
</UserControl.InputBindings>

لكني أرى 2 قضايا:

1) لا أعتقد أن هناك طريقة لمعرفة ما إذا كانت العجلة قد تم تحريكها لأعلى أو لأسفل ، ولا يمكنني رؤية كيفية تحديد مقدار ما. لقد رأيت mousewheeleventargs.delta ، لكن ليس لدي أي فكرة عن كيفية الحصول عليها.

2) لا يبدو الربط بأمر على ViewModel صحيحًا ، لأنه أمر عرض صارم.

نظرًا لأن Zoom هو عرض واجهة المستخدم بدقة فقط ، فأنا أفكر في أن الكود الفعلي يجب أن يذهب في الكود.

كيف ستنفذ هذا يا رفاق؟

PS ، أنا أستخدم .NET WPF 4.0 باستخدام Cinch لـ MVVM.

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

المحلول

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

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

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

نصائح أخرى

anwser الحقيقي هو كتابة Mousegesture الخاصة بك ، وهو أمر سهل.

<MouseBinding Gesture="{x:Static me:MouseWheelGesture.CtrlDown}"  
              Command="me:MainVM.SendBackwardCommand" />

public class MouseWheelGesture : MouseGesture
{
    public static MouseWheelGesture CtrlDown
        => new MouseWheelGesture(ModifierKeys.Control) { Direction = WheelDirection.Down


    public MouseWheelGesture(): base(MouseAction.WheelClick)
    {
    }

    public MouseWheelGesture(ModifierKeys modifiers) : base(MouseAction.WheelClick, modifiers)
    {
    }

    public WheelDirection Direction { get; set; }

    public override bool Matches(object targetElement, InputEventArgs inputEventArgs)
    {
        if (!base.Matches(targetElement, inputEventArgs)) return false;
        if (!(inputEventArgs is MouseWheelEventArgs args)) return false;
        switch (Direction)
        {
            case WheelDirection.None:
                return args.Delta == 0;
            case WheelDirection.Up:
               return args.Delta > 0;
            case WheelDirection.Down:
                return args.Delta < 0;
            default:
                return false;
        }
    }



    public enum WheelDirection
    {
      None,
      Up,
      Down,
    }

}

إذا كنت لا ترغب في استخدام التعليمات البرمجية وراءك ، فيمكنك استخدام وظيفة EventTocommand لضوء MVVM:

رأي:

 <...
     xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
 xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
     ...> 
<i:Interaction.Triggers>
         <i:EventTrigger EventName="PreviewMouseWheel">
             <cmd:EventToCommand Command="{Binding
     Path=DataContext.ZoomCommand,
     ElementName=Root, Mode=OneWay}"
         PassEventArgsToCommand="True"   />
         </i:EventTrigger> </i:Interaction.Triggers>

ViewModel:

ZoomCommand = new RelayCommand<RoutedEventArgs>(Zoom);
...
public void Zoom(RoutedEventArgs e)
{
    var originalEventArgs = e as MouseWheelEventArgs;
    // originalEventArgs.Delta contains the relevant value
}

آمل أن يساعد هذا شخص ما. أعلم أن السؤال قديم ...

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

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

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

الحقيقة هي أن الطريقة الوحيدة للحصول على mouseeventargs (وبالتالي الدلتا) هي في الكود وراء ، لذا احصل على ما تحتاجه هناك (لا يوجد منطق مطلوب لذلك) ونقله إلى نموذج العرض الخاص بك كما اقترح OLLI.

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

لتجنب المشكلة بأكملها ، هناك خيار آخر: -استخدم محتوى المحتوى في XAML ودعه محتوى ملزم بكائن ViewModel. -هندل أحداث mousewheel داخل ViewModel.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top