سؤال

هل يعرف أحد كيف يمكنني إجباره CanExecute للحصول على دعا في أمر مخصص (جوش سميث RelayCommand)?

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

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

كيف يمكنني إجبار تحديث في التعليمات البرمجية عندما يغير المؤقت الخاصية الخاصية التي تؤثر CanExecuteب حاولت إطلاق النار PropertyChanged (INotifyPropertyChanged) على الممتلكات التي تؤثر CanExecute, ، لكن هذا لم يساعد.

مثال XAML:

<Button Content="Button" Command="{Binding Cmd}"/>

مثال الرمز وراء:

private ICommand m_cmd;
public ICommand Cmd
{
    if (m_cmd == null)
        m_cmd = new RelayCommand(
            (param) => Process(),
            (param) => EnableButton);

    return m_cmd;
}

// Gets updated from a timer (not direct user interaction)
public bool EnableButton { get; set; }
هل كانت مفيدة؟

نصائح أخرى

كنت على دراية ب CommandManager.invalideTerequerygested () منذ زمن طويل، واستخدمها، لكنها لم تكن تعمل في بعض الأحيان. أحسب أخيرا لماذا كان هذا هو الحال! على الرغم من أنه لا يرمي مثل بعض الإجراءات الأخرى، يجب عليك الاتصال به على الخيط الرئيسي.

يبدو أن الاتصال به في مؤشر ترابط الخلفية يعمل، ولكن في بعض الأحيان يترك المعوقين UI. آمل حقا أن يساعد هذا شخص ما، ويحفظهم الساعات التي أهدرتها فقط.

الحل البديل لذلك هو ملزم IsEnabled إلى الممتلكات:

<Button Content="Button" Command="{Binding Cmd}" IsEnabled="{Binding Path=IsCommandEnabled}"/>

ثم قم بتنفيذ هذه الخاصية في ViewModel الخاص بك. هذا يجعل من الأسهل بعض الشيء على العمل مع الخصائص بدلا من الأوامر لمعرفة ما إذا كان الأمر يمكن تنفيذ الأمر في وقت معين.

أنا شخصيا، ابحث عنها أكثر ملاءمة.

ربما يناسبك هذا البديل:

 public interface IRelayCommand : ICommand
{
    void UpdateCanExecuteState();
}

التنفيذ:

 public class RelayCommand : IRelayCommand
{
    public event EventHandler CanExecuteChanged;


    readonly Predicate<Object> _canExecute = null;
    readonly Action<Object> _executeAction = null;

   public RelayCommand( Action<object> executeAction,Predicate<Object> canExecute = null)
    {
        _canExecute = canExecute;
        _executeAction = executeAction;
    }


    public bool CanExecute(object parameter)
    {
       if (_canExecute != null)
            return _canExecute(parameter);
        return true;
    }

    public void UpdateCanExecuteState()
    {
        if (CanExecuteChanged != null)
            CanExecuteChanged(this, new EventArgs());
    }



    public void Execute(object parameter)
    {
        if (_executeAction != null)
            _executeAction(parameter);
        UpdateCanExecuteState();
    }
}

باستخدام بسيط:

public IRelayCommand EditCommand { get; protected set; }
...
EditCommand = new RelayCommand(EditCommandExecuted, CanEditCommandExecuted);

 protected override bool CanEditCommandExecuted(object obj)
    {
        return SelectedItem != null ;
    }

    protected override void EditCommandExecuted(object obj)
    {
        // Do something
    }

   ...

    public TEntity SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            _selectedItem = value;

            //Refresh can execute
            EditCommand.UpdateCanExecuteState();

            RaisePropertyChanged(() => SelectedItem);
        }
    }

XAML:

<Button Content="Edit" Command="{Binding EditCommand}"/>

الرجال شكرا للنصائح. إليك القليل من التعليمات البرمجية حول كيفية الاستنشاد الذي اتصل من موضوع BG إلى مؤشر ترابط UI:

private SynchronizationContext syncCtx; // member variable

في المنشئ:

syncCtx = SynchronizationContext.Current;

على خيط الخلفية، لتشغيل Requerery:

syncCtx.Post( delegate { CommandManager.InvalidateRequerySuggested(); }, null );

امل ان يساعد.

-- ميخائيل

لتحديث فقط galasoft.mvvmlight.commandwpf.relaycommand يمكنك استخدامه

mycommand.RaiseCanExecuteChanged();

بالنسبة لي لقد قمت بإنشاء طريقة تمديد:

public static class ExtensionMethods
    {
        public static void RaiseCanExecuteChangedDispatched(this RelayCommand cmd)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { cmd.RaiseCanExecuteChanged(); }));
        }

        public static void RaiseCanExecuteChangedDispatched<T>(this RelayCommand<T> cmd)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { cmd.RaiseCanExecuteChanged(); }));
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top