ডাব্লুপিএফ - কীভাবে কোনও কমান্ডকে তার কমান্ডবাইন্ডিংসের মাধ্যমে 'CanExecute' পুনরায় মূল্যায়ন করতে বাধ্য করা যায়


130

আমার এমন একটি রয়েছে Menuযেখানে MenuItemশ্রেণিবদ্ধের প্রত্যেকটির নিজের Commandসম্পত্তিটিকে RoutedCommandআমি সংজ্ঞায়িত করে সেট করে । সম্পর্কিত প্রতিটি CommandBindingমূল্যায়িত স্থিতি CanExecuteনিয়ন্ত্রণ করে যার মূল্যায়নের জন্য একটি কলব্যাক সরবরাহ করে MenuItem

এটি প্রায় কাজ করে। মেনু আইটেমগুলি প্রাথমিকভাবে সঠিক সক্ষম এবং অক্ষম রাজ্যের সাথে উপস্থিত হয়। যাইহোক, যখন আমার CanExecuteকলব্যাকের ডেটাগুলি পরিবর্তিত হয় তখন আমার নতুন কলটিটি ইউআইতে প্রতিবিম্বিত হওয়ার জন্য আমার কলব্যাক থেকে ফলাফল পুনরায় অনুরোধ করার জন্য কমান্ডের প্রয়োজন হয়।

এটির জন্য RoutedCommandবা এর CommandBindingজন্য কোনও পাবলিক পদ্ধতি রয়েছে বলে মনে হয় না ।

মনে রাখবেন যে আমি যখন ক্লিক বা নিয়ন্ত্রণে টাইপ করি তখন কলব্যাক আবার ব্যবহৃত হয় (আমার ধারণা এটি ইনপুটটিতে ট্রিগার হয়েছে কারণ মাউস-ওভার রিফ্রেশের কারণ নয়) doesn't

উত্তর:


172

বইটিতে সবচেয়ে সুন্দর নয়, আপনি কমান্ড ম্যানেজারটি সমস্ত কমান্ডবাইন্ডিং অকার্যকর করতে ব্যবহার করতে পারেন:

CommandManager.InvalidateRequerySuggested();

এমএসডিএন- তে আরও তথ্য দেখুন


1
ধন্যবাদ এটি ঠিক কাজ করেছে। ইউআইতে কিছুটা বিলম্ব হয়েছে, তবে আমি সে সম্পর্কে খুব বেশি চিন্তিত নই। এছাড়াও, আমি আপনার উত্তরটি তত্ক্ষণাত আপ-ভোটাভুটি দিয়েছি, তারপরে ভোট কার্যকর হয়েছে কিনা তা দেখার জন্য ভোটটি ফিরিয়ে নিয়েছি। এখন এটি কাজ করছে, আমি আবার ভোটটি প্রয়োগ করতে পারি না। নিশ্চিত নয় কেন এসও এর নিয়মটি স্থিতিতে রয়েছে।
ড্রয় নোকস

5
আমার ভোটটি পুনরায় প্রয়োগ করার জন্য আমি আপনার উত্তর সম্পাদনা করেছি। আমি সম্পাদনায় কিছুই পরিবর্তন করি নি। আবার ধন্যবাদ.
ড্রয় নোকস

কোড-পেছন থেকে কোনও টেক্সবক্সের সামগ্রী পরিবর্তন করার সময় আমার একই সমস্যা হয়েছিল। আপনি যদি হাত দ্বারা এটি সম্পাদনা করেন তবে এটি কার্যকর হবে। এই অ্যাপ্লিকেশনে, তাদের কাছে টেক্সবক্সটি এমন একটি নিয়ন্ত্রণ দ্বারা সম্পাদিত হয়েছিল যা পপআপ করবে এবং আপনি যখন পপআপটি সংরক্ষণ করবেন তখন এটি টেক্সবক্স.টেক্সট সম্পত্তি পরিবর্তন করবে। এই সমস্যার সমাধান! ধন্যবাদ @ আর্টাকরাস
জিজান

10
অন্যান্য উত্তর (থেকে মাত্র নোট stackoverflow.com/questions/783104/refresh-wpf-command ) "এটা UI 'তে থ্রেডে নামক করা হয়েছে"
Samvel Siradeghyan

84

যে কেউ পরে এই জুড়ে আসে; আপনি যদি এমভিভিএম এবং প্রিজম ব্যবহার করে থাকেন তবে প্রিজমের DelegateCommandবাস্তবায়ন এটি ICommandকরার একটি .RaiseCanExecuteChanged()পদ্ধতি সরবরাহ করে।


12
এই প্যাটার্নটি অন্যান্য এমভিভিএম লাইব্রেরিতেও পাওয়া যায়, যেমন এমভিভিএম লাইট।
পিটার লিলিভোল্ড

2
প্রিজমের বিপরীতে, এমভিভিএম লাইট ভি 5 এর উত্স কোডটি এর RaiseCanExecuteChanged() সহজ কলগুলি নির্দেশ করে CommandManager.InvalidateRequerySuggested()
পিটার

4
ডাব্লুপিএফ-তে এমভিভিএম লাইটের একটি পক্ষের নোট, আপনাকে গ্যালসফট.এমভিভিএমলাইট.কমন্ড ডাব্লুপিএফ ব্যবহার করতে হবে কারণ গ্যালসফট.এমভিভিএমলাইট.কম্যান্ড সমস্যার সৃষ্টি করবে mvvmlight.net/installing/changes#v5_0_2
fuchs777

((RelayCommand)MyCommand).RaiseCanExecuteChanged();আমার জন্য গ্যালাসফট.এমভিভিএমলাইট.কম্যান্ড ব্যবহার করে - কিন্তু পরিবর্তনের পরে CommandWPFএটি কোনও কল করার প্রয়োজন ছাড়াই কাজ করেছে। ধন্যবাদ @ fuchs777
রবিন বেনেট

1
আপনি যদি তৃতীয় পক্ষের গ্রন্থাগারটি ব্যবহার না করেন তবে কী হবে?
ভিডার

28

CommandManager.InvalidateRequerySuggested();পারফরম্যান্স হিট হওয়ায় আমি ব্যবহার করতে পারিনি।

আমি এমভিভিএম হেল্পারের ডেলিগেটিং কমান্ডটি ব্যবহার করেছি, যা দেখতে নীচের মত দেখাচ্ছে (আমি এটি আমাদের বার্তার জন্য কিছুটা টুইট করেছি)। আপনাকে command.RaiseCanExecuteChanged()ভিএম থেকে কল করতে হবে

public event EventHandler CanExecuteChanged
{
    add
    {
        _internalCanExecuteChanged += value;
        CommandManager.RequerySuggested += value;
    }
    remove
    {
        _internalCanExecuteChanged -= value;
        CommandManager.RequerySuggested -= value;
    }
}

/// <summary>
/// This method can be used to raise the CanExecuteChanged handler.
/// This will force WPF to re-query the status of this command directly.
/// </summary>
public void RaiseCanExecuteChanged()
{
    if (canExecute != null)
        OnCanExecuteChanged();
}

/// <summary>
/// This method is used to walk the delegate chain and well WPF that
/// our command execution status has changed.
/// </summary>
protected virtual void OnCanExecuteChanged()
{
    EventHandler eCanExecuteChanged = _internalCanExecuteChanged;
    if (eCanExecuteChanged != null)
        eCanExecuteChanged(this, EventArgs.Empty);
}

3
শুধু একটি এফওয়াইআই আমি মন্তব্য করেছি কমান্ডম্যানেজ.আরউকেউসসগস্টেড + = মান; আমি কোনও কারণে আমার CanExecute কোডটির কাছাকাছি স্থির / লুপিং মূল্যায়ন পাচ্ছিলাম। অন্যথায় সমাধানটি প্রত্যাশার মতো কাজ করেছিল। ধন্যবাদ!
রোবাউদাস

15

আপনি যদি নিজের ক্লাসটি কার্যকর করে থাকেন তবে ICommandআপনি স্বয়ংক্রিয় স্ট্যাটাস আপডেটগুলি হারাতে পারেন যা আপনাকে প্রয়োজনের তুলনায় ম্যানুয়াল রিফ্রেশিংয়ের উপর নির্ভর করতে বাধ্য করে re এটিও ভেঙে যেতে পারে InvalidateRequerySuggested()। সমস্যাটি হ'ল একটি সাধারণ ICommandবাস্তবায়ন নতুন কমান্ডের সাথে লিঙ্ক করতে ব্যর্থ হয় CommandManager

সমাধানটি নিম্নলিখিতটি ব্যবহার করা হয়:

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void RaiseCanExecuteChanged()
    {
        CommandManager.InvalidateRequerySuggested();
    }

এইভাবে গ্রাহকরা CommandManagerআপনার শ্রেণীর পরিবর্তে সংযুক্ত হন এবং কমান্ডের স্থিতি পরিবর্তনে যথাযথভাবে অংশ নিতে পারেন।


2
সোজাসাপ্টা, বিন্দুতে এবং লোকেরা তাদের আইকোমন্ড বাস্তবায়নের উপর নিয়ন্ত্রণ রাখতে দেয়।
আকোই মেক্সেক্স

2

কমান্ডগুলির উপর সম্পত্তি নির্ভরতা হ্যান্ডেল করার জন্য আমি একটি সমাধান প্রয়োগ করেছি, এখানে লিঙ্কটি https://stackoverflow.com/a/30394333/1716620

আপনাকে ধন্যবাদ যে আপনি এই মত একটি কমান্ড শেষ হবে:

this.SaveCommand = new MyDelegateCommand<MyViewModel>(this,
    //execute
    () => {
      Console.Write("EXECUTED");
    },
    //can execute
    () => {
      Console.Write("Checking Validity");
       return PropertyX!=null && PropertyY!=null && PropertyY.Length < 5;
    },
    //properties to watch
    (p) => new { p.PropertyX, p.PropertyY }
 );

-3

এটিই আমার পক্ষে কাজ করেছিল: এক্সএএমএল-এর কমান্ডের আগে কান এক্সেকিউট রাখুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.