2010-10-29 104 views
2

我有许多我的窗体(使用WeifenLuo.WinFormsUI.Docking)需要与之交互的对象集合。使用winforms实现观察者模式

即,如果集合具有以一种形式进行的添加(或删除),则其他形式通过刷新其视图来作出响应。

显然,观察者模式在这里是一个很好的候选人。但是,我正在试图在我的程序中实现这个问题。

首先,它似乎最好创建一个观察者类我的收藏,像这样:

public class DataCollectionObserver : Form 
{ 
    internal static void DataCollectionRegister(DataCollection dataCollection) 
    { 
     dataCollection.ImageAdded += new EventHandler(dataAdded); 
     dataCollection.ImageRemoved += new EventHandler(dataRemoved); 
     dataCollection.ImageIndexChanged += new EventHandler(dataIndexChanged); 
     dataCollection.ImageListCleared += new EventHandler(dataListCleared); 
    } 

    internal static void DataCollectionUnRegister(DataCollection dataCollection) 
    { 
     dataCollection.ImageAdded -= new EventHandler(dataAdded); 
     dataCollection.ImageRemoved -= new EventHandler(dataRemoved); 
     dataCollection.ImageIndexChanged -= new EventHandler(dataIndexChanged); 
     dataCollection.ImageListCleared -= new EventHandler(dataListCleared); 
    } 

    internal static void dataAdded(object sender, EventArgs e) {} 
    internal static void dataRemoved(object sender, EventArgs e) {} 
    internal static void dataIndexChanged(object sender, EventArgs e) {} 
    internal static void dataListCleared(object sender, EventArgs e) {} 
} 

然后覆盖基本的事件处理程序子类的形式?

但是,我不能做到这一点,使用WeifenLuo.WinFormsUI.Docking库...

好了,我可以从DataCollectionObserver继承WeifenLuo.WinFormsUI.Docking DockContent,但产生了一种情况,我需要有两个DataCollectionObserver类 - 一个它继承形式,另一种是继承DockContent: - [ 或者,我可以让DataCollectionObserver接口,但是仍然给我留下了重复的代码铺设约...

因此,没有人在这里有一个建议吗?我是否错过了一些明显的东西,或者这是为了简单起见,必须重复执行代码的情况?


编辑://

我没有得到通知,我的形式问题

。事实上,整个事情现在都在运作。我问的原因是因为整个事情“闻起来”是由于我有这些订阅集合事件和取消订阅Form.Closing()这四种不同形式的代码块复制和粘贴。

我想要做的是实现我在一个地方复制并粘贴到这四个表单的行为,并让表单根据需要收到集合更改通知。

希望让事情更清楚?

FWIW,这是我的集合类:

using System; 
using System.Collections; 
using System.Reflection; 

namespace MyNameSpace.Collections 
{ 
    /// <summary> 
    /// Generic Collection of Objects with Events 
    /// </summary> 
    public class CollectionWithEvents<T> : CollectionBase 
    { 
     public bool SuppressEventNotification 
     { 
      get; 
      set; 
     } 

     public CollectionWithEvents() 
     { 
      SuppressEventNotification = false; 
     } 

     #region Events 
     /// <summary> 
     /// Raises before an item is added to the list. 
     /// </summary> 
     public event EventHandler<ItemEventArgs<T>> BeforeItemAdded; 

     /// <summary> 
     /// Raises when an item is added to the list. 
     /// </summary> 
     public event EventHandler<ItemEventArgs<T>> ItemAdded; 

     /// <summary> 
     /// Raises before a collection of items is added to the list. 
     /// </summary> 
     public event EventHandler<ItemsEventArgs<T>> BeforeItemsAdded; 

     /// <summary> 
     /// Raises when a collection of items is added to the list. 
     /// </summary> 
     public event EventHandler<ItemsEventArgs<T>> ItemsAdded; 

     /// <summary> 
     /// Raises before an item is changed in the list. 
     /// </summary> 
     public event EventHandler<ItemEventArgs<T>> BeforeItemChanged; 

     /// <summary> 
     /// Raises when an item is changed in the list. 
     /// </summary> 
     public event EventHandler<ItemEventArgs<T>> ItemChanged; 

     /// <summary> 
     /// Raises before an item is removed from the list. 
     /// </summary> 
     public event EventHandler<ItemEventArgs<T>> BeforeItemRemoved; 

     /// <summary> 
     /// Raises when an item is removed from the list. 
     /// </summary> 
     public event EventHandler<ItemEventArgs<T>> ItemRemoved; 

     /// <summary> 
     /// Raises when the items are cleared from the list. 
     /// </summary> 
     public event EventHandler<EventArgs> ItemsCleared; 
     #endregion 

     public T this[int index] 
     { 
      get { return (T)this.List[index]; } 
      set 
      { 
       if (!SuppressEventNotification) 
       { 
        OnBeforeItemChanged(this, new ItemEventArgs<T>(value)); 
       } 

       this.List[index] = value; 

       if (!SuppressEventNotification) 
       { 
        OnItemChanged(this, new ItemEventArgs<T>(value)); 
       } 
      } 
     } 

     public int Add(T item) 
     { 
      if (!SuppressEventNotification) 
      { 
       OnBeforeItemAdded(this, new ItemEventArgs<T>(item)); 
      } 

      int retValue = this.List.Add(item); 

      if (!SuppressEventNotification) 
      { 
       OnItemAdded(this, new ItemEventArgs<T>(item)); 
      } 

      return retValue; 
     } 

     public void AddRange(Collection<T> collection) 
     { 
      T[] tmp = new T[collection.Count]; 

      collection.CopyTo(tmp, 0); 

      AddRange(tmp); 
     } 

     public void AddRange(T[] collection) 
     { 
      if (!SuppressEventNotification) 
      { 
       OnBeforeItemsAdded(this, new ItemsEventArgs<T>(collection)); 
      } 

      this.AddRange(collection); 

      if (!SuppressEventNotification) 
      { 
       OnItemsAdded(this, new ItemsEventArgs<T>(collection)); 
      } 
     } 

     public bool Contains(T item) 
     { 
      return this.List.Contains(item); 
     } 

     public void CopyTo(Array array, int index) 
     { 
      this.List.CopyTo(array, index); 
     } 

     public int IndexOf(T item) 
     { 
      return this.List.IndexOf(item); 
     } 

     public void Insert(int index, T item) 
     { 
      this.List.Insert(index, item); 
     } 

     public void Remove(T item) 
     { 
      if (!SuppressEventNotification) 
      { 
       OnBeforeItemRemoved(this, new ItemEventArgs<T>(item)); 
      } 

      T tmp = (T)item; 

      this.List.Remove(item); 

      if (!SuppressEventNotification) 
      { 
       OnItemRemoved(this, new ItemEventArgs<T>(tmp)); 
      } 

      tmp = default(T); 
     } 

     public void Sort(string Property, Common.SortOrder Order) 
     { 
      Common.GenericComparer genericComparer = new Common.GenericComparer(Property, Order); 
      this.InnerList.Sort(genericComparer); 
     } 

     #region Event Methods 
     /// <summary> 
     /// Raised before an Item is added to the list. 
     /// </summary> 
     /// <param name="sender">object</param> 
     /// <param name="e">ItemEventArgs</param> 
     protected virtual void OnBeforeItemAdded(object sender, ItemEventArgs<T> e) 
     { 
      if (BeforeItemAdded != null) 
      { 
       BeforeItemAdded(sender, e); 
      } 
     } 

     /// <summary> 
     /// Raised when an Item is added to the list. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e">ItemEventArgs</param> 
     protected virtual void OnItemAdded(object sender, ItemEventArgs<T> e) 
     { 
      if (ItemAdded != null) 
      { 
       ItemAdded(sender, e); 
      } 
     } 

     /// <summary> 
     /// Raised before a collection of Items is added to the list. 
     /// </summary> 
     /// <param name="sender">object</param> 
     /// <param name="e">ItemEventArgs</param> 
     protected virtual void OnBeforeItemsAdded(object sender, ItemsEventArgs<T> e) 
     { 
      if (BeforeItemsAdded != null) 
      { 
       BeforeItemsAdded(sender, e); 
      } 
     } 

     /// <summary> 
     /// Raised when a collection of Items is added to the list. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e">ItemEventArgs</param> 
     protected virtual void OnItemsAdded(object sender, ItemsEventArgs<T> e) 
     { 
      if (ItemsAdded != null) 
      { 
       ItemsAdded(sender, e); 
      } 
     } 

     /// <summary> 
     /// Raised before an Item is changed to the list. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e">GenericItemEventArgs</param> 
     protected virtual void OnBeforeItemChanged(object sender, ItemEventArgs<T> e) 
     { 
      if (BeforeItemChanged != null) 
      { 
       BeforeItemChanged(sender, e); 
      } 
     } 

     /// <summary> 
     /// Raised when an Item is changed to the list. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e">ItemEventArgs</param> 
     protected virtual void OnItemChanged(object sender, ItemEventArgs<T> e) 
     { 
      if (ItemChanged != null) 
      { 
       ItemChanged(sender, e); 
      } 
     } 

     /// <summary> 
     /// Raised before an Item is removed from the list. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e">ItemEventArgs</param> 
     protected virtual void OnBeforeItemRemoved(object sender, ItemEventArgs<T> e) 
     { 
      if (BeforeItemRemoved != null) 
      { 
       BeforeItemRemoved(sender, e); 
      } 
     } 

     /// <summary> 
     /// Raised when an Item is removed from the list. 
     /// </summary> 
     /// <param name="sender">object</param> 
     /// <param name="e">ItemEventsArgs</param> 
     protected virtual void OnItemRemoved(object sender, ItemEventArgs<T> e) 
     { 
      if (ItemRemoved != null) 
      { 
       ItemRemoved(sender, e); 
      } 
     } 

     /// <summary> 
     /// Raised when the Items are cleared from this list. 
     /// </summary> 
     /// <param name="sender">object</param> 
     /// <param name="e">EventArgs</param> 
     protected virtual void OnItemsCleared(object sender, EventArgs e) 
     { 
      if (ItemsCleared != null) 
      { 
       ItemsCleared(sender, e); 
      } 
     } 
     #endregion 
    } 

    public class ItemEventArgs<T> : EventArgs 
    { 
     /// <summary> 
     /// Item 
     /// </summary> 
     public T Item { get; private set; } 

     /// <summary> 
     /// Default constructor 
     /// </summary> 
     /// <param name="Item"></param> 
     public ItemEventArgs(T Item) 
     { 
      this.Item = Item; 
     } 
    } 

    public class ItemsEventArgs<T> : EventArgs 
    { 
     /// <summary> 
     /// Items 
     /// </summary> 
     public T[] Items { get; private set; } 

     /// <summary> 
     /// Default constructor 
     /// </summary> 
     /// <param name="Items"></param> 
     public ItemsEventArgs(T[] Items) 
     { 
      this.Items = Items; 
     } 
    } 
} 

回答

1

.NET的版本,您使用的是否为> = 3.5,你可以利用的ObservableCollection的才达到你在做什么都

1

在框架中有一个'ObservableCollection'就是为了这种类型的东西。见here

2

我可能会误解。但是你可以这样做,你的继承问题就不存在了。我会尽力举一个简单的例子:

您的集合类可能是这样的:

public class MyCollection 
    { 
     IList<string> MyList { get; set; } 

     public event EventHandler<StringEventArgs> OnAdded; 
     public event EventHandler<StringEventArgs> OnRemoved; 

     public MyCollection() 
     { 
      MyList = new List<string>(); 
     } 

     public void Add(string s) 
     { 
      MyList.Add(s); 

      if (OnAdded != null) 
       OnAdded(this, new StringEventArgs() { StringAddedOrRemoved = s }); 
     } 

     public void Remove(string s) 
     { 
      MyList.Remove(s); 
      if (OnRemoved != null) 
       OnRemoved(this, new StringEventArgs() { StringAddedOrRemoved = s }); 
     } 
    } 

真正简单的类有两个自定义事件处理:

public class StringEventArgs : EventArgs 
    { 
     public string StringAddedOrRemoved; 


     public override string ToString() 
     { 
      return StringAddedOrRemoved; 
     } 
    } 

没有很难理解这里然后基于这三种形式,你可以这样使用你的形式。

第一个拥有两个按钮与集合交互并创建两种形式,将观察您的收藏:

public partial class Form1 : Form 
    { 
     public static MyCollection collection; 


     public Form1() 
     { 

      InitializeComponent(); 

      collection = new MyCollection(); 

      Form2 form2 = new Form2(); 
      form2.Show(); 

      Form3 form3 = new Form3(); 
      form3.Show(); 

      collection.OnAdded += form2.MyCollectionAdded; 
      collection.OnRemoved += form2.MyCollectionRemoved; 

      collection.OnAdded += form3.MyCollectionAdded; 
      collection.OnRemoved += form3.MyCollectionRemoved; 

     } 

     private void Add_Click(object sender, EventArgs e) 
     { 
      collection.Add("test add"); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      collection.Remove("test add"); 
     } 


    } 

收集被连接到每一个将要观察这里的业态功能:

collection.OnAdded += form2.MyCollectionAdded; 
       collection.OnRemoved += form2.MyCollectionRemoved; 

       collection.OnAdded += form3.MyCollectionAdded; 
       collection.OnRemoved += form3.MyCollectionRemoved; 

因此,我们需要实现这些形式:

public partial class Form2 : Form 
    { 


     public string Name { get; set; } 
     public bool Flag { get; set; } 

     public Form2() 
     { 
      InitializeComponent(); 
     } 

     public void MyCollectionAdded(object sender, StringEventArgs e) 
     { 
      //Some action 
      Flag = true; 
      label1.Text = string.Format("{0} has added {1} to its list, flag={2}", Name, e.StringAddedOrRemoved, Flag); 
     } 

     public void MyCollectionRemoved(object sender, StringEventArgs e) 
     { 
      //Some action 
      Flag = false; 
      label1.Text = string.Format("{0} has removed {1} from its list, flag={2}", Name, e.StringAddedOrRemoved, Flag); 
     } 
    } 

我从窗体继承我的东西,但它可以从任何你想要的实际上继承。如果你想在不同的表单中分享一些代码,可以考虑静态类中的助手函数,或者任何适合你需要的模式。

希望它有一点帮助,而且我不完全超出范围!

[编辑]哎呀没有看到编辑,对不起朋友![/编辑]