আমি কীভাবে কর্সারটিকে অপেক্ষার কার্সারে পরিণত করতে পারি?


263

আমার কাছে একটি সি # অ্যাপ্লিকেশন রয়েছে যাতে ব্যবহারকারীরা এতে লগইন করেছেন এবং হ্যাশিং অ্যালগরিদম ব্যয়বহুল হওয়ায় এটি করতে কিছুটা সময় নেয়। আমি কীভাবে ওয়েট / ব্যজি কার্সার (সাধারণত ঘড়িঘড়ি) ব্যবহারকারীর কাছে তাদের কিছু জানাতে পারি যে প্রোগ্রামটি কিছু করছে?

প্রকল্পটি সি # তে রয়েছে।

উত্তর:


451

আপনি ব্যবহার করতে পারেন Cursor.Current

// Set cursor as hourglass
Cursor.Current = Cursors.WaitCursor;

// Execute your time-intensive hashing code here...

// Set cursor as default arrow
Cursor.Current = Cursors.Default;

তবে, যদি হ্যাশিং অপারেশনটি সত্যই দীর্ঘ হয় (এমএসডিএন এটি 2-7 সেকেন্ডেরও বেশি হিসাবে সংজ্ঞায়িত করে), আপনার সম্ভবত অগ্রগতির ব্যবহারকারীকে অবহিত করার জন্য কার্সার ব্যতীত ভিজ্যুয়াল প্রতিক্রিয়া সূচক ব্যবহার করা উচিত। নির্দেশিকাগুলির আরও গভীর-সেট করার জন্য, এই নিবন্ধটি দেখুন

সম্পাদনা:
@ আম্মার নির্দেশ অনুসারে, ঘন্টাঘড়িটি বাস্তবে প্রদর্শিত হয়েছে তা নিশ্চিত করার জন্য আপনাকে কল করার Application.DoEvents();পরে প্রয়োজন হতে পারে Cursor.Current = Cursors.WaitCursor;


23
এটি কার্সার পরিবর্তন করতে প্রয়োজনীয় হবে না - যদি সময়-নিবিড় কোডের সময় বার্তা লুপটি কল করা না হয়। এটি সক্ষম করার জন্য আপনাকে অ্যাপ্লিকেশন যোগ করতে হবে o ডভেন্টস (); প্রথম কার্সার সেট পরে।
আমিরশাক

16
আপনি খুব সম্ভবত কারেন্ট সেট করার পরে একটি চেষ্টা..ফিনালি ব্লক করতে চান (সুনিশ্চিত করে যে বর্তমান ডিফল্টে রিসেট হয়ে যায়)।
ট্রুউইল

7
এফওয়াইআই, আমি উপরের কাজটি করতে পারিনি, তবে এটি এটিকে পরিবর্তিত করে এটিকে .c এটা কাজ করেছে.
হান্স রুডেল

4
আমি যদি কার্সার পরে অ্যাপ্লিকেশন.ডাউনভেন্টস () ব্যবহার করি তবে হরগ্লাস প্রদর্শিত হবে না urrent নিশ্চিত কেন নয়
ভিবিপি

14
এটি ব্যবহার করা আরও ভাল Application.UseWaitCursor = trueএবংApplication.UseWaitCursor = false
Gianpiero

169

আসলে,

Cursor.Current = Cursors.WaitCursor;

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

ওয়েট কার্সারটি দেখানোর আরও ভাল উপায় হ'ল UseWaitCursor প্রপার্টিটি সত্য রূপে সেট করা:

form.UseWaitCursor = true;

আপনি এই সম্পত্তিটিকে মিথ্যা হিসাবে সেট না করা পর্যন্ত এটি ফর্মের সমস্ত নিয়ন্ত্রণের জন্য অপেক্ষার কার্সার প্রদর্শন করবে। আপনি যদি অ্যাপ্লিকেশন স্তরে অপেক্ষা কার্সারটি দেখানোর জন্য চান তবে আপনার ব্যবহার করা উচিত:

Application.UseWaitCursor = true;

জানা ভাল. আমি ডাব্লুপিএফ-তেও একই কাজ করার চেষ্টা করছিলাম এবং আমি কার্সার = কার্সার.ওয়েট এবং কার্সার = কার্সার.আরও দিয়ে শেষ করেছি । তবে আমি অ্যাপটির
sh

2
অ্যাপ্লিকেশনের অধীনে UseWaitCursor খুঁজে পাওয়া যায় নি!
চন্দ্র এসকে

অপারেশন শেষে ফর্মটি সেট করার সময় আমি খুঁজে পেয়েছি Uউপস ওয়েটক্রসার = মিথ্যা, আপনি মাউসটি সরিয়ে না নেওয়া বা ক্লিক না করা পর্যন্ত এটি আসলে কার্সারটিকে পুনরায় সেট করে না। OTOH, form.Cursor এ সমস্যা নেই। আমি কার্সারকে পাইনি work কাজটি করার জন্য মোটেই কাজ করিনি।
স্টিয়ার্ট

39

পূর্ববর্তীটি নির্মাণে, আমার পছন্দসই পদ্ধতির (যেহেতু এটি প্রায়শই সম্পাদিত ক্রিয়া হয়) হ'ল ওয়েড কার্সার কোডটি একটি আইডিস্পোজযোগ্য সহায়ক শ্রেণিতে আবৃত করা যাতে এটি () (কোডের একটি লাইন) ব্যবহার করে ব্যবহার করা যায়, alচ্ছিক পরামিতিগুলি গ্রহণ করুন, রান করুন কোডটির মধ্যে, তারপরে পরিষ্কার করুন (কার্সার পুনরুদ্ধার করুন) পরে।

public class CursorWait : IDisposable
{
    public CursorWait(bool appStarting = false, bool applicationCursor = false)
    {
        // Wait
        Cursor.Current = appStarting ? Cursors.AppStarting : Cursors.WaitCursor;
        if (applicationCursor) Application.UseWaitCursor = true;
    }

    public void Dispose()
    {
        // Reset
        Cursor.Current = Cursors.Default;
        Application.UseWaitCursor = false;
    }
}

ব্যবহার:

using (new CursorWait())
{
    // Perform some code that shows cursor
}

: দ্বারা অনুপ্রাণিত codeproject.com/Articles/6287/WaitCursor-hack-using-using
কুঁদ

এটি দেখেনি, তবে হ্যাঁ অনুরূপ পন্থা। তিনি বর্তমান কার্সারটিকে ব্যাক আপ করেন তারপরে এটি পুনরুদ্ধার করেন, আপনি যদি ভারী কার্সার পরিবর্তন করে থাকেন তবে তা কার্যকর হতে পারে।
এমএপ্পস

27

ফর্ম বা উইন্ডো স্তরে UseWaitCursor ব্যবহার করা সহজ । সাধারণ ব্যবহারের ক্ষেত্রে নীচের মত দেখতে পাওয়া যায়:

    private void button1_Click(object sender, EventArgs e)
    {

        try
        {
            this.Enabled = false;//optional, better target a panel or specific controls
            this.UseWaitCursor = true;//from the Form/Window instance
            Application.DoEvents();//messages pumped to update controls
            //execute a lengthy blocking operation here, 
            //bla bla ....
        }
        finally
        {
            this.Enabled = true;//optional
            this.UseWaitCursor = false;
        }
    }

আরও ভাল ইউআই অভিজ্ঞতার জন্য আপনার আলাদা থ্রেড থেকে অ্যাসিঙ্ক্রোনি ব্যবহার করা উচিত।


2
এটি স্বীকৃত উত্তর হওয়া উচিত। এটিই একমাত্র চেষ্টা করে যা শেষ পর্যন্ত চেষ্টা করে।
জন হেন্কেল 20'15

1
আমার উত্সাহটি দেখুন, অবশেষে আমার বাস্তবায়নে একটি অনুপস্থিত ছিল
জ্যাক

19

আমার পদ্ধতির ব্যাকগ্রাউন্ড কর্মী সমস্ত গণনা করা হবে।

তারপরে কার্সারটি এভাবে পরিবর্তন করুন:

this.Cursor = Cursors.Wait;

এবং থ্রেডের সমাপ্ত ইভেন্টে কার্সারটি পুনরুদ্ধার করুন:

this.Cursor = Cursors.Default;

দ্রষ্টব্য, এটি নির্দিষ্ট নিয়ন্ত্রণগুলির জন্যও করা যেতে পারে, সুতরাং কার্সারটি কেবল তখন মাউস তাদের উপরে থাকবে তখন ঘন্টাঘড়ি হবে।


@ ম্যালফিস্ট: ভাল দৃষ্টিভঙ্গি :), তারপরে আপনাকে যা করতে হবে তা হ'ল শেষ ইভেন্টে পুনরুদ্ধার করা এবং আপনার কাজ শেষ।
আমিরশাক

4

ঠিক আছে তাই আমি একটি স্থির async পদ্ধতি তৈরি করেছি। এটি অ্যাকশন আরম্ভ করে এমন নিয়ন্ত্রণ অক্ষম করে এবং অ্যাপ্লিকেশন কার্সরকে পরিবর্তন করে এটি কার্য হিসাবে অ্যাকশনটি চালায় এবং শেষ হওয়ার জন্য অপেক্ষা করে। কলারের অপেক্ষা করা অবস্থায় ফিরে আসা নিয়ন্ত্রণ করুন। তাই অ্যাপ্লিকেশনটি প্রতিক্রিয়াশীল থাকবে, এমনকি ব্যস্ত আইকনটি স্পিন করার পরেও।

async public static void LengthyOperation(Control control, Action action)
{
    try
    {
        control.Enabled = false;
        Application.UseWaitCursor = true;
        Task doWork = new Task(() => action(), TaskCreationOptions.LongRunning);
        Log.Info("Task Start");
        doWork.Start();
        Log.Info("Before Await");
        await doWork;
        Log.Info("After await");
    }
    finally
    {
        Log.Info("Finally");
        Application.UseWaitCursor = false;
        control.Enabled = true;
    }

এখানে কোডটি মূল ফর্মটি দেয়

    private void btnSleep_Click(object sender, EventArgs e)
    {
        var control = sender as Control;
        if (control != null)
        {
            Log.Info("Launching lengthy operation...");
            CursorWait.LengthyOperation(control, () => DummyAction());
            Log.Info("...Lengthy operation launched.");
        }

    }

    private void DummyAction()
    {
        try
        {
            var _log = NLog.LogManager.GetLogger("TmpLogger");
            _log.Info("Action - Sleep");
            TimeSpan sleep = new TimeSpan(0, 0, 16);
            Thread.Sleep(sleep);
            _log.Info("Action - Wakeup");
        }
        finally
        {
        }
    }

ডামি অ্যাকশনের জন্য আমাকে একটি পৃথক লগার ব্যবহার করতে হয়েছিল (আমি এনলগ ব্যবহার করছি) এবং আমার প্রধান লগারটি ইউআইতে (একটি সমৃদ্ধ পাঠ্য বাক্স) লিখছেন। আমি কেবলমাত্র ফর্মের কোনও নির্দিষ্ট ধারককে কেন্দ্র করে ব্যস্ত কার্সর প্রদর্শন করতে সক্ষম হইনি (তবে আমি খুব কঠিন চেষ্টা করিনি)) সমস্ত নিয়ন্ত্রণের একটি UseWaitCursor সম্পত্তি রয়েছে তবে এটি নিয়ন্ত্রণগুলিতে কোনও প্রভাব ফেলবে বলে মনে হয় না seem আমি চেষ্টা করেছি (সম্ভবত তারা শীর্ষে ছিল না বলে?)

এখানে মূল লগ, যা জিনিসগুলি প্রত্যাশা অনুযায়ী ক্রম ঘটছে তা দেখায়:

16:51:33.1064 Launching lengthy operation...
16:51:33.1215 Task Start
16:51:33.1215 Before Await
16:51:33.1215 ...Lengthy operation launched.
16:51:49.1276 After await
16:51:49.1537 Finally

2

নীচের শ্রেণীর সাহায্যে আপনি ডোনাট "ব্যতিক্রম নিরাপদ" পরামর্শটি করতে পারেন।

using (new CursorHandler())
{
    // Execute your time-intensive hashing code here...
}

ক্লাস কার্সরহ্যান্ডলার

public class CursorHandler
    : IDisposable
{
    public CursorHandler(Cursor cursor = null)
    {
        _saved = Cursor.Current;
        Cursor.Current = cursor ?? Cursors.WaitCursor;
    }

    public void Dispose()
    {
        if (_saved != null)
        {
            Cursor.Current = _saved;
            _saved = null;
        }
    }

    private Cursor _saved;
}

2

ওকে, অন্যান্য লোকের দৃষ্টিভঙ্গি খুব স্পষ্ট, তবে আমি নিম্নলিখিত হিসাবে কিছু যুক্ত করতে চাই:

Cursor tempCursor = Cursor.Current;

Cursor.Current = Cursors.WaitCursor;

//do Time-consuming Operations         

Cursor.Current = tempCursor;

2

উইন্ডোজ ফর্ম অ্যাপ্লিকেশনগুলির জন্য একটি ইউআই-নিয়ন্ত্রণের একটি ofচ্ছিক অক্ষম করা খুব কার্যকর হতে পারে। সুতরাং আমার পরামর্শটি এর মতো দেখাচ্ছে:

public class AppWaitCursor : IDisposable
{
    private readonly Control _eventControl;

    public AppWaitCursor(object eventSender = null)
    {
         _eventControl = eventSender as Control;
        if (_eventControl != null)
            _eventControl.Enabled = false;

        Application.UseWaitCursor = true;
        Application.DoEvents();
    }

    public void Dispose()
    {
        if (_eventControl != null)
            _eventControl.Enabled = true;

        Cursor.Current = Cursors.Default;
        Application.UseWaitCursor = false;
    }
}

ব্যবহার:

private void UiControl_Click(object sender, EventArgs e)
{
    using (new AppWaitCursor(sender))
    {
        LongRunningCall();
    }
}

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