【问题标题】:How to add/remove items from a list from a different form?如何从不同表单的列表中添加/删除项目?
【发布时间】:2017-02-21 07:43:36
【问题描述】:

假设我的主表单中有一个名为listOfFruits 的列表。在我制作的第二种形式中,我希望用户能够从该列表中删除项目到名为removedFruits 的第二个列表中。目前我知道我可以在我的第二种形式中访问这些列表,只需将它们作为参数传递给表单构造函数。但是 c# 不能做指针(正确吗?)那么我怎样才能从我的第二个表单中影响这些列表的主表单副本呢?因为目前在我的第二个表单中对这些列表的任何更改都不会影响主表单的列表原始副本。如果我要从传递给我的第二个表单的listOfFruits 中删除 5 个水果,那么在完成我的工作后,主表单仍然会有一个完整的listOfFruits 和一个空的removedFruits。有一个简单的解决方法吗?也许是获取/设置或从第二种形式的原始列表中添加/删除项目的方法?也许答案是某种访问器的东西?

编辑:澄清;我想添加到一个列表,并从另一个列表中删除。不添加/删除到同一个列表。不确定这是否完全重要,但我想我会在这里具体说明以防万一。

EDIT2:我认为问题是我从第一个表单中复制原始列表,而不是直接编辑它。有人可以修复我的代码,以便我可以从第二个表单访问原始列表,而不是复制列表吗?

public partial class ListSelector : Form
    {
        private string windowName = Form1.typeOfModuleAdded;
        public List<IOModule> innerIOList;
        IOModule cardAdded = null;

        public ListSelector(List<IOModule> cardList)
        {
            this.Text = windowName;
            innerIOList = cardList;
            InitializeComponent();
            InitializeList();
        }
    private void InitializeList()
    {
        if (windowName == "Drive")
        {
            string[] listDrives = { "ACS880", "test" };
            listBox1.Items.AddRange(listDrives);
        }

        else if (windowName == "IOBlock")
        {
            if (!innerIOList.Any())
            {
                MessageBox.Show("No cards loaded! Please import cards from IO List.", "Error Empty Data", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
            foreach (IOModule card in innerIOList)
            {
                cardAdded = card;
                listBox1.Items.Add(card.name);
            }
        }
        else if (windowName == "Local Card")
        {
            string[] listLocals = { "1756-EN2T", "test" };
            listBox1.Items.AddRange(listLocals);
        }
        else if (windowName == "Processor")
        {
            string[] listProcessors = { "1756-L71S", "test" };
            listBox1.Items.AddRange(listProcessors);
        }
    }

    private void addBtn_Click(object sender, EventArgs e)
    {
        if (listBox1.SelectedItem != null)
        {
            Form1.SetModule(listBox1.SelectedItem.ToString());
            Form1.confirmedAdd = true; 
            this.Close();
        }
        else if (cardAdded != null)
        {
            innerIOList.Remove(cardAdded);
        }
        else
        {
            MessageBox.Show("No module selected!");
        }
    }

下面是我如何将列表从我的第一个表单传递到该表单:

        ListSelector test = new ListSelector(ioList);
        test.ShowDialog();

其中 ListSelector 是我的第二个表单的名称,ioList 是我传递给它的列表。

EDIT3:添加了更多代码

【问题讨论】:

  • 您能否展示您遇到问题的代码,然后我们可以为您提供更多帮助? :)
  • 如何创建一个新的 .cs 文件(和一个新类)并将这些列表作为静态变量放在此类中,并从两种形式中引用它们。例如MyStatics.ListOfFruits 和 MyStatics.RemovedFruits。
  • List&lt;T&gt; 是引用类型,当您将其传递给另一个表单时,您在列表中所做的所有更改也将在您的第一个表单中可见。可能您已经从原始列表中创建了另一个列表(使用 ToList 或其他内容),这就是您看不到原始列表中的更改的原因。
  • 您似乎正在直接访问列表。您的问题可能是,您对 List 的更改未反映在您的 UI(即您的 ListBoxes)中。无论您编辑我认为的列表,您都必须手动执行此操作。
  • 你可能会发现这篇文章很有用:Connect List<T> to a ListBox

标签: c# forms winforms list accessor


【解决方案1】:

“但是 c# 不能做指针(正确吗?)那么我如何才能从我的第二个表单中影响主表单的这些列表的副本?”

不,不正确。任何对象引用(例如,List&lt;Fruit&gt;)在很大程度上仍然是指向内存中某个位置的指针,如果您将相同的 List&lt;Fruit&gt; 对象传递给两个 Form,它们共享相同的 List。

我不知道为什么您对listOfFruits 的更改在您的第一个表单中没有出现。我会检查以下内容:

  1. 您是否 100% 确定在两个表单中使用相同的 List&lt;Fruit&gt; 对象。 (如果您像这样创建一个新列表:new List&lt;Fruit&gt;(listOfFruits) 它不是同一个列表)

  2. 第一个Form 是否有任何方法可以发现列表已更改?可以使用带有重复检查的计时器,或者(我最喜欢的)在您更改某些内容时触发event,并在第一个Form 中订阅EventHandlerevent

【讨论】:

  • 我做了,似乎不完整,InitializeList 是做什么的?
  • @TheHowlingHoaschld 添加了更多信息和解释
【解决方案2】:

我假设您在第二个表单中创建了第二个列表,其中填充了第一个表单列表中的项目。然后第二个列表上的更改不会反映在第一个列表中。您必须使用列表的相同引用。

public Form2(List<Fruit> listOfFruits)
{
    this._listOfFruits = listOfFruits;
}

private List<Fruit> _listOfFruits;

【讨论】:

  • 您提供的代码是否复制了原始列表?这就是我的感觉。如果不介意解释为什么不呢?我真的看不出我写的和你在这里看到的有什么区别。因为我写的只是复制,不直接影响原单。 :(
  • @CapnJack:没有副本,我只是将相同的引用分配给另一个变量。由于列表是引用类型,所有更改也将反映第一种形式的列表。
【解决方案3】:

尝试使用属性,而不是使用公共字段,并在创建新的 ListSelector 时将列表传递给属性。

public partial class ListSelector : Form
{
    private string windowName = Form1.typeOfModuleAdded;
    private List<IOModule> innerIOList;
    IOModule cardAdded = null;

    public List<IOModule> CardList 
    {
         get 
         {
              return innerIOList; 
         }
         set
         {
              innerIOList = value;
              InitializeList();
         }
    }

    public ListSelector()
    {
        this.Text = windowName;
        InitializeComponent();
    }

创建新的 ListSelector 对象时

ListSelector ls = new ListSelector();
ls.CardList = your mainform list of IOModule here
ls.ShowDialog();

【讨论】:

  • 等一下,如果您没有将原始列表从第一个表单传递到此表单,您如何获取该列表信息?
  • @CapnJack 不,您可以使用代码的第二行传递列表,请参见 ls.CardList = your mainform list of IOModule here,还编辑了属性以匹配在您的代码编辑上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 1970-01-01
  • 1970-01-01
  • 2016-05-09
相关资源
最近更新 更多