1

My situation:

I have a populated checklistbox control on Form1. Then I have a listView control on Form2.

I would like for the user to be able to check items on the checklistbox on Form1, then click on a button on Form1 to open Form2.

Form2 contains the listView control, that I want to populate with only the checked items from checklistbox on Form1.

I tried

namespace Boodschappenlijst
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

    public static string[] strKruideniersw = new string[] { Boodschappenlijst.producten[0], Boodschappenlijst.producten[1], Boodschappenlijst.producten[2] };
    public static string[] strVerswaren = new string[] { Boodschappenlijst.producten[3], Boodschappenlijst.producten[4], Boodschappenlijst.producten[5] };
    public static string[] strVerzorgingspr = new string[] { Boodschappenlijst.producten[6], Boodschappenlijst.producten[7], Boodschappenlijst.producten[8], Boodschappenlijst.producten[9] };

    public static List<string> kruidenierswList = new List<string>(strKruideniersw);
    public static List<string> verswarenList = new List<string>(strVerswaren);
    public static List<string> verzproductenList = new List<string>(strVerzorgingspr);

    public static string[] strKruidenierswCh;

    public void Form1_Load(object sender, EventArgs e)
    {
        clbKruidenierswaren.Items.AddRange(strKruideniersw);
        clbVerswaren.Items.AddRange(strVerswaren);
        clbVerzproducten.Items.AddRange(strVerzorgingspr);
        strKruidenierswCh = clbKruidenierswaren.CheckedItems;
    }

    // TODO
    // public string kruidenierswChecked = clbKruidenierswaren.CheckedItems;


    private void button1_Click(object sender, EventArgs e)
    {
        // Create a new instance of the Form2 class
        Form2 form2 = new Form2();

        // Show the settings form
        form2.Show();
    }
}

public abstract class Boodschappenlijst : Form1
{
    public static string[] producten = new string[] { "Peper", "Zout", "Kruidnagel", "Sla", "Komkommer", "Tomaten", "Tandpasta", "Shampoo", "Wax", "Deodorant" };

    // Not working.. clbKruidenierswaren is not static.
    List<string> items = clbKruidenierswaren.CheckedItems.Cast<string>().ToList();

    // Make form1 controls accessible for other classes?
    // Form1 form1 = Application.OpenForms.OfType<Form1>().FirstOrDefault();



}
}

but the I get the error

A field initializer cannot reference the non-static field, method, or property 'Form1.clbKruidenierswaren'.

Can you please direct me to a solution that works?

Nasreddine
  • 36,610
  • 17
  • 75
  • 94
  • Instead of passing the `checkboxlist` to the ctor, pass the list of selected ids instead like `List`. Then populate your `ListView` based on the ids rather than the checkboxes. If you want to pass data to a `Form` when creating it, create a `BaseForm` class that inherits `Form` and just put a property like `object InitialisationData {get;set;}`. – Dan Rayson Jul 07 '17 at 09:11
  • @Dan Rayson: Can you please provide me with an example? This does not yet make alot of sense to me, to be honest.. – Richard Postma Jul 07 '17 at 09:13
  • Hoi Richard ;), What I see is that you populate your list in multiple ways, is the idea behind it that you are learning or that you are actually implementing this? Because there are some things that might need an overhaul.. – Blaatz0r Jul 07 '17 at 09:15
  • Hoi Blaatz0r, Well, I am new to C#, and learning. Please comment on my code if it does not make sense to you and tell me what I need to change to make this work. :) – Richard Postma Jul 07 '17 at 09:17
  • @RichardPostma I can see you're dutch :P why is the class abstract though? – EpicKip Jul 07 '17 at 09:17
  • @EpicKip, something I was also pondering on. Next to that Richard, I am already working on it and refactoring plus commenting the code. – Blaatz0r Jul 07 '17 at 09:23
  • @EpicKip: the class Boodschappenlijst should not be abstract, sorry about that. But I do need an abstract class Product, with subclasses Kruidenierswaren and Verswaren. I will be adding that later. – Richard Postma Jul 07 '17 at 09:35
  • @RichardPostma To load the class with the list just make a constructor like in my answer – EpicKip Jul 07 '17 at 09:38

3 Answers3

0

The problem is you're passing UI objects around, you should be passing data around instead. Here's an example of a Form that can be given data during construction.

public class BaseForm : Form
{
    public object InitialisationData { get; set; }
}

public partial class MagicForm : BaseForm
{
    public string MyBindableGuy;

    public MagicForm()
    {
        InitializeComponent();

        MyBindableGuy = InitialisationData as string;
    }
}

and open it with:

var myForm = new MagicForm();
myForm.InitialisationData = "Hi, I'm a string.";
myForm.Show();
Dan Rayson
  • 1,315
  • 1
  • 14
  • 37
0

You should make a constructor in the class like this:

Class itself:

public class Boodschappenlijst
{
    public static string[] producten { get; set; } = new string[] { "Peper", "Zout", "Kruidnagel", "Sla", "Komkommer", "Tomaten", "Tandpasta", "Shampoo", "Wax", "Deodorant" };
    private List<string> Items { get; set; }

    public Boodschappenlijst(List<string> items)// << Constructor
    {
        Items = items;
    }
}

And then make an instance the class like so:

On the place (Form?) you have clbKruidenierswaren:

Boodschappenlijst boodschappenLijst = 
           new Boodschappenlijst(clbKruidenierswaren.CheckedItems.Cast<string>().ToList());
EpicKip
  • 4,015
  • 1
  • 20
  • 37
  • Thanks for your answer, EpicKip. But now I get the error "The name 'clbKruidenierswaren' does not exist in the current context" in this piece of code: `Boodschappenlijst boodschappenLijst = new Boodschappenlijst(clbKruidenierswaren.CheckedItems.Cast().ToList());` – Richard Postma Jul 07 '17 at 09:54
  • It should work, but you can access the items by property because its private (so if you want that swap to public ;)) – EpicKip Jul 07 '17 at 09:55
  • You have to make that instance in the form where the combobox is – EpicKip Jul 07 '17 at 09:57
  • The instance is in `Form1`, where the `CheckedListBox` control is also present. – Richard Postma Jul 07 '17 at 10:02
  • @RichardPostma if it says `clbKruidenierswaren` doesnt exist... it doesnt exist. Are you sure you are at the correct place? Maybe you are in a static method? try in a normal one – EpicKip Jul 07 '17 at 10:04
  • @RichardPostma Maybe try it in the button click or at the bottom of the form load – EpicKip Jul 07 '17 at 10:05
  • I appreciate your effort. But still struggling to understand what we're doing with your above piece of code.. :) – Richard Postma Jul 07 '17 at 10:42
  • 1
    @RichardPostma Making an instance of a class... maybe ask your teacher or something because that's basic oop stuff. - edited so maybe its more clear. If you want we could go in a chatroom and I could explain in dutch – EpicKip Jul 07 '17 at 11:34
  • I would second that I think Epic and myself could give you plenty of info :) – Blaatz0r Jul 07 '17 at 13:16
0
public partial class Form1 : Form
{
    // Todo declare the variables
    private List<string> kruidenierswList;
    private List<string> verswarenList;
    private List<string> verzproductenList;

    public Form1()
    {
        InitializeComponent();

        // call the instance once and add that to the variable lijst
        Boodschappenlijst lijst = Boodschappenlijst.Instance; // <- @ others on S/O this is just used as information I know I could do a new as well.

        // initialize the variables
        kruidenierswList = new List<string>() { lijst.Products[0], lijst.Products[1], lijst.Products[2] };
        verswarenList = new List<string>() { lijst.Products[3], lijst.Products[4], lijst.Products[5] };
        verzproductenList = new List<string>() { lijst.Products[6], lijst.Products[7], lijst.Products[8], lijst.Products[9] };
    }

    public void Form1_Load(object sender, EventArgs e)
    {
        // populate the checklist boxes
        clbKruidenierswaren.Items.AddRange(kruidenierswList.ToArray());
        clbVerswaren.Items.AddRange(verswarenList.ToArray());
        clbVerzproducten.Items.AddRange(verzproductenList.ToArray());
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // Create a new instance of the Form2 class
        Form2 form2 = new Form2();

        // Show the settings form
        form2.Show();
    }
}

public class Boodschappenlijst
{
    private static Boodschappenlijst instance;

    public string[] Products
    {
        get;
        private set;
    }

    private Boodschappenlijst()
    {
        Products = new string[] { "Peper", "Zout", "Kruidnagel", "Sla", "Komkommer", "Tomaten", "Tandpasta", "Shampoo", "Wax", "Deodorant" };
    }

    public static Boodschappenlijst Instance
    {
        get
        {
            // singleton initialization => look for design pattern - singleton  <- Design patterns can brighten your day.
            // 
            return instance == null ? instance = new Boodschappenlijst() : instance;
        }
    }
}
Blaatz0r
  • 1,205
  • 1
  • 12
  • 24