我一直想知道如何正确地做到这一点,但我不完全确定。
我想创建一个用户名列表,并使用foreach循环将用户名绘制到屏幕上。用户名列表是一个静态列表,它将保存在MainClass中,绘图过程将在另一个类中进行(对于这个实例,我们将其称为Printer类)。
我的'问题'是我想要这样做,以便我不只是将那个List从MainClass复制到一个单独的List到Printer类中,所以当我从列表中添加/删除一个对象时,Printer类可以立刻告诉它已经改变了。
编辑:我不需要担心列表更改的事件,因为列表将打印在Paint事件上。我主要需要在Printer类中创建一个新变量,并在首次初始化类时将该变量与相关List“链接”
我不能简单地在打印机内部使用MainClass.usernameList,因为它将同时用于多个列表,复制MainClass列表只会为我提供一个永不更新的列表(除非我告诉它但是这可能会变得乏味有很多同时上课)。
我假设我需要使用指针,但我以前从未使用它们,并且整个不安全代码的想法似乎......不安全。
要点: 我需要在公共类中创建一个指向另一个类中的静态List的变量。
代码非常邋but但希望人们能够更好地了解我想要实现的目标:
答案 0 :(得分:2)
我认为你的问题不应该以你的方式解决;无论如何,如果你使用 ObservableCollection ,你可以在列表中添加和删除元素时得到通知,然后你就可以做出反应。
此外,如果你的列表是静态的,你不需要传递引用,但如果你这样做,你仍然引用同一个对象,所以你总是有更新的列表。
答案 1 :(得分:1)
您可以将列表设为ObservableCollection<T>
,然后在绑定到您的集合的CollectionChanged
事件的其他类中实现逻辑。
因此,您只需将集合存储在有用的位置,然后在帮助程序类或控件中或您需要的任何位置实现CollectionChanged
事件的事件处理程序。只要集合的内容发生变化,就会调用事件处理程序:
myCollection.CollectionChanged += SomeHelperClass.OnCollectionChanged;
并在您的助手班中编写
public void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// process e.NewItems
...
// process e.OldItems
...
}
另见http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx。
答案 2 :(得分:1)
您不需要不安全的阻止。默认情况下,所有对象都是引用,不会复制内容。
var x = new List<int>() { 1, 2, 3 };
var printer = new Printer();
// this assignment does not copy the list - it assigns the property to the same list
printer.UserList = x;
// verify that the reference was copied, not the data
x.Add(4);
printer.UserList.Add(5);
MessageBox.Show(x.Count.ToString()); // shows 5
MessageBox.Show(printer.UserList.Count.ToString()); // also shows 5
这是class
和struct
之间的主要区别。如果你有一个struct
,那么它将被复制所有的整数,DateTime
等变量。
答案 3 :(得分:0)
我没有看到任何人回答的方法可以让您倾听 List<T>
中发生的事情。
为此,您需要为列表创建一个基本的小包装器,其中至少包含一个您需要连接的EventHandler对象。
这是我刚刚聚集在一起的一个非常基本的实现:
public class SubscribeList<T> : IList<T> {
private List<T> list;
public EventHandler OnListContentsChange;
public SubscribeList() {
list = new List<T>();
}
public int IndexOf(T item) {
return list.IndexOf(item);
}
public void Insert(int index, T item) {
list.Insert(index, item);
OnListContentsChange(this, EventArgs.Empty);
}
public void RemoveAt(int index) {
list.RemoveAt(index);
OnListContentsChange(this, EventArgs.Empty);
}
public T this[int index] {
get {
throw new NotImplementedException(); // do this if you want,
}
set {
throw new NotImplementedException(); // but it is more complicated
}
}
public void Add(T item) {
list.Add(item);
OnListContentsChange(this, EventArgs.Empty);
}
public void Clear() {
list.Clear();
OnListContentsChange(this, EventArgs.Empty);
}
public bool Contains(T item) {
return list.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex) {
list.CopyTo(array, arrayIndex);
OnListContentsChange(this, EventArgs.Empty);
}
public int Count {
get { return list.Count; }
}
public bool IsReadOnly {
get { return false; }
}
public bool Remove(T item) {
var ok = list.Remove(item);
if (ok) {
OnListContentsChange(this, EventArgs.Empty);
}
return ok;
}
public IEnumerator<T> GetEnumerator() {
foreach (var item in list) yield return item;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return list.GetEnumerator();
}
}
现在,你这么说:
摘要:我需要在公共类中创建一个指向另一个类中的静态List的变量。
好的,让我们从另一个类中的静态List开始。不要笑:
public class AnotherClass {
public static SubscribeList<String> List;
static AnotherClass() {
List = new SubscribeList<string>();
List.OnListContentsChange += new EventHandler(List_ContentsChanged);
}
private static void List_ContentsChanged(object sender, EventArgs e) {
Console.WriteLine("The contents of the list have changed! Call your Redraw Code.");
}
}
必须连接OnListContentsChanged
EventHandler,以便您的代码知道在列表更改时如何做出反应。
现在,要在指向此列表的公共类中创建变量,您可以执行以下操作:
public class PublicClass {
private SubscribeList<String> list;
public PublicClass() {
list = AnotherClass.List;
}
private void someButton_Click(object sender, EventArgs e) {
list.Add("Someone or txtName.Text from your form"); // this will fire the AnotherClass.List_ContentsChanged EventHandler.
}
}
注意我创建了一个虚构的按钮点击事件,它将一个项目添加到您的静态列表中。
另外,请注意,如果AnotherClass
中的列表从未创建过,那么您将在此处抛出异常。
如果那不是你想要的,那么我根本就不明白你的问题。