.NET এ অবজারভেবল কালেকশন এর ব্যবহার কী?


227

.NET এ অবজারভেবল কালেকশন এর ব্যবহার কী?


1
@ আলফা-মাউস: আপনি যে সমস্যার সমাধান করার চেষ্টা করছেন সে সম্পর্কে আপনি কি আরও কিছু তথ্য দিতে পারেন? এটি আপনাকে প্রাসঙ্গিক উদাহরণ দিতে লোকদের সহায়তা করবে।
জাজা

@ জাজা: আমি সবেমাত্র প্রশ্নের ট্যাগগুলি পরিবর্তন করেছি =) আমি সন্তোষের প্রশ্ন নয়
আলফা-মাউস

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

উত্তর:


224

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

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

class Handler
{
    private ObservableCollection<string> collection;

    public Handler()
    {
        collection = new ObservableCollection<string>();
        collection.CollectionChanged += HandleChange;
    }

    private void HandleChange(object sender, NotifyCollectionChangedEventArgs e)
    {
        foreach (var x in e.NewItems)
        {
            // do something
        }

        foreach (var y in e.OldItems)
        {
            //do something
        }
        if (e.Action == NotifyCollectionChangedAction.Move)
        {
            //do something
        }
    }
}

21
e.NewItemsএবং e.OldsItemsক্রিয়া উপর নির্ভর করে শূন্য হতে পারে। এটা ছুড়ে দিতে পারে NullReferenceException
ডভিড

7
সিডেনোট: যখন অ্যাকশন সরানো হবে, তখন সরানো উপাদানটি নিউ আইটেম এবং ওল্ড আইটেম উভয়তেই উপস্থিত হবে
বোহদান_ট্রোটসেনক

এর জন্য আপনাকে ধন্যবাদ:> ডাব্লুপিএফ এর মধ্যে ইতিমধ্যে নির্মিত
ইউআইকে

157

একটি ObservableCollectionইন্টারফেস প্রয়োগ করে ব্যতীত একটি নিয়মিত সংগ্রহের মতো মূলত কাজ করে:

যেমন সংগ্রহটি কখন বদলেছে তা আপনি জানতে চাইলে এটি খুব দরকারী। একটি ইভেন্ট ট্রিগার করা হয়েছে যা ব্যবহারকারীকে জানায় যে কোন এন্ট্রি যুক্ত / সরানো হয়েছে বা সরানো হয়েছে।

আরও গুরুত্বপূর্ণভাবে কোনও ফর্মে ডেটাবাইন্ডিং ব্যবহার করার সময় এগুলি খুব কার্যকর।


54

থেকে প্রো সি # 5.0 এবং .NET 4.5 ফ্রেমওয়ার্ক

ObservableCollection<T>শ্রেণী (সঙ্গে কাজ, যেমন আপনি অনুমান করতে পারে এটা বাইরের বস্তুর যখন এটির সামগ্রীগুলি কিছু উপায় পরিবর্তিত হয়েছে অবহিত করার ক্ষমতা থাকবে যে খুবই দরকারী ReadOnlyObservableCollection<T>অনুরূপ, কিন্তু শুধুমাত্র পাঠযোগ্য প্রকৃতিতে)। এই ক্লাস উভয়ই একই কোর ইন্টারফেস বাস্তবায়ন করে, অনেক দিক থেকে, ObservableCollection<T>একই সাথে কাজ করা List<T>সমান। ObservableCollection<T>ক্লাসটি কী অনন্য করে তোলে তা হল এই শ্রেণিটি নামের একটি ইভেন্টকে সমর্থন করে CollectionChanged। এই ইভেন্টটি যখনই কোনও নতুন আইটেম সন্নিবেশ করা হবে, কোনও বর্তমান আইটেম সরানো হবে (বা স্থানান্তরিত হয়েছে), বা যদি পুরো সংগ্রহটি সংশোধন করা হয় তখনই এই ইভেন্টটি ছড়িয়ে যাবে। যে কোনও ইভেন্টের মতো, কালেকশন চেঞ্জড একটি প্রতিনিধি হিসাবে সংজ্ঞায়িত করা হয়, যা এই ক্ষেত্রে NotifyCollectionChangedEventHandler। এই প্রতিনিধি যে কোনও পদ্ধতিতে কল করতে পারে যা কোনও বস্তুকে প্রথম প্যারামিটার হিসাবে গ্রহণ করে এবং কNotifyCollectionChangedEventArgsদ্বিতীয় হিসাবে নিম্নলিখিত প্রধান () পদ্ধতিটি বিবেচনা করুন, যা ব্যক্তি অবজেক্ট এবং CollectionChangedইভেন্টটি সজ্জিত করে একটি পর্যবেক্ষণযোগ্য সংগ্রহকে জনপ্রিয় করে তোলে :

class Program
{
   static void Main(string[] args)
   {
     // Make a collection to observe and add a few Person objects.
     ObservableCollection<Person> people = new ObservableCollection<Person>()
     {
        new Person{ FirstName = "Peter", LastName = "Murphy", Age = 52 },
        new Person{ FirstName = "Kevin", LastName = "Key", Age = 48 },
     };
     // Wire up the CollectionChanged event.
     people.CollectionChanged += people_CollectionChanged;
     // Now add a new item.
     people.Add(new Person("Fred", "Smith", 32));

     // Remove an item.
     people.RemoveAt(0);

     Console.ReadLine();
   }
   static void people_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
   {
       // What was the action that caused the event?
        Console.WriteLine("Action for this event: {0}", e.Action);

        // They removed something. 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
        {
            Console.WriteLine("Here are the OLD items:");
            foreach (Person p in e.OldItems)
            {
                Console.WriteLine(p.ToString());
            }
            Console.WriteLine();
        }

        // They added something. 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
        {
            // Now show the NEW items that were inserted.
            Console.WriteLine("Here are the NEW items:");
            foreach (Person p in e.NewItems)
            {
                Console.WriteLine(p.ToString());
            }
        }
   }
}

আগত NotifyCollectionChangedEventArgsপ্যারামিটার দুটি গুরুত্বপূর্ণ বৈশিষ্ট্য সংজ্ঞায়িত করে OldItemsএবং NewItemsযা আপনাকে ইভেন্টটি বহিষ্কারের আগে সংগ্রহের মধ্যে থাকা আইটেমগুলির একটি তালিকা এবং পরিবর্তনের সাথে জড়িত নতুন আইটেমগুলির তালিকা দেয়। তবে আপনি কেবল সঠিক পরিস্থিতিতে এই তালিকাগুলি পরীক্ষা করতে চাইবেন। স্মরণ করুন যে আইটেমগুলি যুক্ত করা, অপসারণ করা, স্থানান্তরিত করা বা পুনরায় সেট করা হলে কালেকশন-চেঞ্জড ইভেন্টটি গুলি চালাতে পারে। এর মধ্যে কোন ক্রিয়াকলাপটি ইভেন্টটিকে ট্রিগার করেছে তা আবিষ্কার করতে আপনি নোটিফোনক্লিকেশনচেনজড এভেন্টআর্গের ক্রিয়া সম্পত্তিটি ব্যবহার করতে পারেন। অ্যাকশন সম্পত্তিটি NotifyCollectionChangedActionগণনার নিম্নোক্ত যে কোনও সদস্যের বিরুদ্ধে পরীক্ষা করা যেতে পারে :

public enum NotifyCollectionChangedAction
{
Add = 0,
Remove = 1,
Replace = 2,
Move = 3,
Reset = 4,
}

সিস্টেম.সংগঠনের সদস্য .অজেক্টমোডেল


1
people_CollectionChanged ঘটনা আগুনে পুড়ে গেলে আমি একজন ব্যক্তি নামে সংগ্রহে (সংগ্রহে নিজেই পরিবর্তন ছাড়া?) পরিবর্তিত হবে
BKSpurgeon

25

কোড ব্যতীত ব্যাখ্যা

এর পিছনে কোনও কোড ছাড়াই উত্তর চান তাদের জন্য (বুম-টিশ) আমি আমার হাত উপরে ফেলে দেব:

সাধারণ সংগ্রহ - কোনও বিজ্ঞপ্তি নেই

প্রতিবার এবং পরে আমি এনওয়াইসিতে যাই এবং আমার স্ত্রী আমাকে স্টাফ কিনতে বলেন। তাই আমি আমার সাথে শপিংয়ের তালিকাটি নিই। তালিকায় সেখানে প্রচুর জিনিস রয়েছে:

  1. লুই ভিটনের হ্যান্ডব্যাগ (5000 ডলার)
  2. ক্লাইভ ক্রিশ্চিয়ানের ইম্পেরিয়াল ম্যাজেস্টি পারফিউম (215,000 ডলার)
  3. গুচি সানগ্লাস (2000 ডলার)

হাহাহাহা ভাল আমি "এই জিনিসটি কিনছি না So সুতরাং আমি এগুলি কেটে ফেলেছি এবং তাদের তালিকা থেকে সরিয়ে দিচ্ছি এবং পরিবর্তে আমি যুক্ত করছি:

  1. 12 ডজন শিরোনামের গল্ফ বল।
  2. 12 পাউন্ড বোলিং বল।

তাই আমি সাধারণত জিনিসপত্র ছাড়াই বাড়িতে আসি এবং সে কখনই সন্তুষ্ট হয় না। বিষয়টি হ'ল তিনি কী জানেন যে আমি কী তালিকাটি সরিয়ে রেখেছি এবং আমি এতে কী যুক্ত করছি; তিনি কোন বিজ্ঞপ্তি পায়।

পর্যবেক্ষণযোগ্য সংগ্রহ - পরিবর্তনগুলি করার সময় বিজ্ঞপ্তি

এখন, যখনই আমি তালিকা থেকে কোনও জিনিস সরিয়ে ফেলি: সে তার ফোনে একটি বিজ্ঞপ্তি পেয়েছে (যেমন এসএমএস / ইমেল ইত্যাদি)!

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

সব মিলিয়ে!


7

বৃহত্তম ব্যবহারগুলির মধ্যে একটি হ'ল আপনি ইউআই উপাদানগুলিকে একটিতে আবদ্ধ করতে পারেন এবং যদি সংগ্রহের বিষয়বস্তু পরিবর্তন হয় তবে তারা যথাযথভাবে প্রতিক্রিয়া জানাবে। উদাহরণস্বরূপ, আপনি যদি একটি তালিকাভিত্তিক আইটেমসোর্সটিকে একটিতে আবদ্ধ করেন, আপনি সংগ্রহটি সংশোধন করেন তবে তালিকাভিউয়ের সামগ্রীগুলি স্বয়ংক্রিয়ভাবে আপডেট হবে।

সম্পাদনা: এমএসডিএন থেকে কিছু নমুনা কোড এখানে দেওয়া হয়েছে: http : //msdn.mic Microsoft.com/en-us/library/ms748365.aspx

সি # তে, লিস্টবক্সকে সংগ্রহের দিকে ঝুলানো তত সহজ হতে পারে

listBox.ItemsSource = NameListData;

যদিও আপনি যদি স্ট্যাটিক রিসোর্স এবং সংজ্ঞায়িত নেম আইটেম টেম্পলেট হিসাবে তালিকাটি আপ না করে থাকেন তবে আপনি পার্সোননামের টসস্ট্রিং () ওভাররাইড করতে চাইতে পারেন। উদাহরণ স্বরূপ:

public override ToString()
{
    return string.Format("{0} {1}", this.FirstName, this.LastName);
}

6

এটি এমন একটি সংগ্রহ যা সংগ্রহের পরিবর্তনের জন্য বেশিরভাগ ইউআইকে অবহিত করতে ব্যবহৃত হয়, এটি স্বয়ংক্রিয়ভাবে বিজ্ঞপ্তি সমর্থন করে।

মূলত ডাব্লুপিএফ,

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


আসলেই কি ঘটে ?? : ও
কিংস

5
class FooObservableCollection : ObservableCollection<Foo>
{
    protected override void InsertItem(int index, Foo item)
    {
        base.Add(index, Foo);

        if (this.CollectionChanged != null)
            this.CollectionChanged(this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Add, item, index);
    }
}

var collection = new FooObservableCollection();
collection.CollectionChanged += CollectionChanged;

collection.Add(new Foo());

void CollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
{
    Foo newItem = e.NewItems.OfType<Foo>().First();
}

আপনি কী ব্যাখ্যা করতে পারবেন কেন FooObservable Colલેક્શન সংগ্রহ বাস্তবায়িত হয়? এবং কেন আপনি অন্তর্ভুক্ত InsertItem?
এরি

@ অ্যারি: সত্যি কথা, 8 বছর পরে আমার মনে নেই, তাই কোনও ধারণা নেই। ডক্সগুলিতে আমি যা দেখছি সেগুলির কোনওটির প্রয়োজন নেই, এটি সমস্তটি বাক্সের বাইরে চলে আসা উচিত।
abatishchev
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.