تمرير معلمة باستخدام RelayCommand المحددة في ViewModel (من مثال Josh Smith)

StackOverflow https://stackoverflow.com/questions/810208

سؤال

أرغب في تمرير معلمة محددة في XAML (عرض) من طلبي إلى فئة ViewModel باستخدام RelayCommand. تتبعت مقال جوش سميث الممتاز عن MVVM وقد نفذت ما يلي.

رمز XAML

        <Button 
        Command="{Binding Path=ACommandWithAParameter}"
        CommandParameter="Orange"
        HorizontalAlignment="Left" 
        Style="{DynamicResource SimpleButton}" 
        VerticalAlignment="Top" 
        Content="Button"/>

رمز ViewModel

  public RelayCommand _aCommandWithAParameter;
  /// <summary>
  /// Returns a command with a parameter
  /// </summary>
  public RelayCommand ACommandWithAParameter
  {
     get
     {
        if (_aCommandWithAParameter == null)
        {
           _aCommandWithAParameter = new RelayCommand(
               param => this.CommandWithAParameter("Apple")
               );
        }

        return _aCommandWithAParameter;
     }
  }

  public void CommandWithAParameter(String aParameter)
  {
     String theParameter = aParameter;
  }
  #endregion

لقد قمت بتعيين نقطة توقف في طريقة commandwithaparameter ولاحظت أنه تم تعيين Aparameter على "Apple" ، وليس "Orange". يبدو هذا واضحًا حيث يتم استدعاء CommandWithAparameter مع السلسلة الحرفية "Apple".

ومع ذلك ، بالنظر إلى مكدس التنفيذ ، يمكنني أن أرى أن "Orange" ، فإن CommandParameter التي قمت بتعيينها في XAML هي قيمة المعلمة الخاصة بـ RelayCommand of the ICommand execute Interface Method.

هذه هي قيمة المعلمة في الطريقة أدناه من مكدس التنفيذ هي "برتقالية" ،

  public void Execute(object parameter)
  {
     _execute(parameter);
  }

ما أحاول اكتشافه هو كيفية إنشاء خاصية relecmomn acommandwithaparameter بحيث يمكنه استدعاء طريقة commandwithaparameter مع commandparameter "Orange" المحددة في XAML.

هل هناك طريقة للقيام بذلك؟

لماذا أريد أن أفعل هذا؟ جزء من "On the Fly Ording" في تنفيذي الخاص ، أريد إنشاء مجموعة من الأزرار setLanguage التي يمكن أن تكون مرتبطة بأزرار متعددة. أرغب في تمرير معرف لغة الحرف ("EN" ، "ES" ، "JA" ، إلخ) باعتباره CommandParameter ويتم تعريفه لكل زر "Language" المحدد في XAML. أريد تجنب الاضطرار إلى إنشاء أمر setLanguageToxxx لكل لغة تدعم وترميز معرف لغة الحرف في كل relayCommand في ViewModel.

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

المحلول

لا أفهم لماذا لديك التعقيد الإضافي لتحديد Lambda في المقام الأول. لماذا لا تفعل هذا فقط:

if (_aCommandWithAParameter == null)
{           
    _aCommandWithAParameter = new RelayCommand<object>(CommandWithAParameter);
}

private void CommandWithAParameter(object state)
{
    var str = state as string;
}

نصائح أخرى

ستقوم بتمرير البرام في Lambda إلى الأمر مثل SO:

if (_aCommandWithAParameter == null)
{           
    _aCommandWithAParameter = new RelayCommand(               
        param => this.CommandWithAParameter(param)
        );        
}

لم يتم نشر شيء هنا من قبل.

تبين ، كل الإجابات مفقودة <object> بعد، بعدما RelayCommand!

هذا يعمل بالنسبة لي:

public RelayCommand<object> OKCommand
{
    get
    {
        if (_okCommand == null)
            _okCommand = new RelayCommand<object>(OkCommand_Execute);
        return _okCommand;
    }
}
private RelayCommand<object> _okCommand = null;

private void OkCommand_Execute(object obj)
{
    Result = true;
}

إذا كنت تريد استخدام أCanExecute الطريقة ، استخدم الكود التالي:

_okCommand = new RelayCommand<object>(OkCommand_Execute, OkCommand_CanExecute);

private bool OkCommand_CanExecute(object obj) { }

أحاول فقط بيع وجهة نظري ، تحقق من ذلك ما إذا كان هذا يعمل ...

http://mywpf-visu.blogspot.com/2009/12/relay-command-how-to-pass-parameter.html

فيما يلي حل بسيط لـ CommandParameter حيث كنت أبحث عن مساعدة في هذا الموضوع. لم أتمكن من العثور على أي شيء عبر الإنترنت كان بسيطًا بما فيه الكفاية. يعمل الحل التالي بشكل جيد عندما تستخدم RelayCommand. كان لدي عدد قليل من الارتباطات التشعبية التي كنت بحاجة للحصول على قيمة عنوان URL الذي تم النقر عليه باستخدام معلمة الأمر.

الخطوة 1: في أمر الترحيل الخاص بك ، قم بإنشاء خاصية بسيطة ستعقد قيمة كائن المعلمة. يمكنك تسميتها parametervalue أو أي اسم تفضله.

public object ParameterValue
{
  get;
  set;
}

الخطوة 2: في طريقة التنفيذ لفئة RelayCommand ، قم بتعيين القيمة أو الخاصية التي تم إنشاؤها أعلاه إلى المعلمة من طريقة التنفيذ.

readonly Action<object> m_execute;       // Action to execute

public void Execute(object parameter)
 {
   this.ParameterValue = parameter;
   m_execute(parameter);
 }

الخطوة 3: الآن عندما يمكنك ربط CommandParameter في XAML بأي قيمة تريد استردادها عند تنفيذ الأمر. مثال:

<TextBlock>
  <Hyperlink Command="{Binding Path=NavigateUrlCmd}"
             CommandParameter="{Binding ElementName=tbwebsite, Path=Text}">
    <TextBlock Name="tbwebsite" Text="{Binding Path=website}"/>
  </Hyperlink>
</TextBlock> 

إذا كان لديك أمر يسمى chickencommand ، عند تنفيذها ، يمكنك الوصول إلى المعلمة: chickencommand.parametervalue

امل ان يساعد هذا احد ما. شكرا لك على كل مساعدتك السابقة.

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

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