New to C#, listview - c#

When I go to run the program it is empty, no data displayed
namespace _0000003
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
soulpets = new ListView();
ListViewItem lvi6001 = soulpets.Items.Add("6001");
lvi6001.SubItems.Add("Tough Ent, Rare");
ListViewItem lvi6004 = soulpets.Items.Add("6004");
lvi6004.SubItems.Add("Stone Fist Ent, Rare");
ListViewItem lvi6007 = soulpets.Items.Add("6007");
lvi6007.SubItems.Add("Healing Ent,Rare");
Controls.Add(soulpets);

soulpets = new ListView();
should be soulpets.Items.Clear();
You probably want:
add a listview via the designer with the name soulpets
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
fillListViewSoulpets();
}
private void fillListViewSoulpets()
{
soulpets.Items.Clear(); //it should already be empty
soulpets.Items.Add(
new ListViewItem({ "Tough", "Ent", "Rare" }),
new ListViewItem({ "Stone", "Fist", "Ent", "Rare" }),
new ListViewItem({ "Healing", "Ent", "Rare" })
);
}
}

Related

I want to use a Button to add the text in a TextBox to a ListView

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new AddItem();
taskList.ItemsSource = new List<AddItem>
{
new AddItem()
{
Title = "Task1",
},
new AddItem()
{
Title = "Task2",
},
};
}
private void addButton_Click(object sender, RoutedEventArgs e)
{
taskList.SelectedItem = new AddItem();
}
I want to add the Text in the TextBox as an AddItem to the ListView using a Button, but I don't know how to add the value to the ListView. The name of the TextBox is inputTitle.
If you intend to modify the collection you have to use an ObservableCollection that supports notifying collection changes through the INotifyCollectionChanged interface that tiggers updating your ListView. List<T> does not support that, so your user interface will not be updated when adding, removing or replacing items in the collection.
public partial class MainWindow : Window
{
private ObservableCollection<AddItem> _myItems;
public MainWindow()
{
InitializeComponent();
DataContext = new AddItem();
_myItems = new ObservableCollection<AddItem>
{
new AddItem()
{
Title = "Task1",
},
new AddItem()
{
Title = "Task2",
},
};
taskList.ItemsSource = _myItems;
}
private void addButton_Click(object sender, RoutedEventArgs e)
{
var newItem = new AddItem()
{
Title = inputTitle.Text,
};
_myItems.Add(newItem);
taskList.SelectedItem = newItem;
}
}
You should consider checking if the Text is empty, so you avoid adding useless items or deactivate the button if the TextBox is empty.

Add ONLY checked items from a checklistbox to a listView control

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?
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());
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();
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;
}
}
}

c# Windows forms 'Object reference not set to an instance of an object'

I come to ask because i'm new using windows forms and i need some help.
I have a Windows Forms project with 2 forms. The MainForm and the InnerForm.
I'm trying to access to a TableLayoutPanel in MainForm from InnerForm to add new rows in this tablelayoutpanel with some actions that happen in the InnerForm.
I have the next code:
MainForm:
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
TableLayoutPanel panel = tableLayoutPanel1;
panel.ColumnCount = 4;
panel.RowCount = 1;
panel.RowStyles.Add(new RowStyle(SizeType.AutoSize, 0));
panel.Controls.Add(new Label() { Text = "Tag/ID" }, 0, 0);
panel.Controls.Add(new Label() { Text = "Tipo" }, 1, 0);
panel.Controls.Add(new Label() { Text = "Acción" }, 2, 0);
panel.Controls.Add(new Label() { Text = "Ejecutar" }, 3, 0);
}
private void AddInnerForm(string url)
{
var inner = new InnerForm(url)
// more code
}
public void agregarRow(ConsoleMessageEvents args){
// some action with tableLayoutPanel1
}
}
InnerForm:
public partial class InnerForm : UserControl
{
MainForm theMain;
public InnerForm(MainForm main)
{
theMain = main;
}
public InnerForm(string url)
{
InitializeComponent();
// more code
}
private void OnBrowserConsoleMessage(object sender, ConsoleMessageEventArgs args)
{
theMain.agregaRow(args);
}
}
but when I'm debugging the program I get this error:
An unhandled exception of type 'System.NullReferenceException' occurred in Project.exe
Additional information: Object reference not set to an instance of an object.
in this line in InnerForm:
private void OnBrowserConsoleMessage(object sender, ConsoleMessageEventArgs args)
{
**theMain.agregaRow(args)**;
}
What is the problem here?
That should fix it. The field theMain was not initialized, also you need to call InitializeComponenets in every constructos to create the child controls.
public partial class InnerForm : UserControl
{
MainForm theMain;
public InnerForm(MainForm main)
{
InitializeComponent();
theMain = main;
}
public InnerForm(string url, MainForm mainForm)
{
this.theMain = mainForm;
InitializeComponent();
// more code
}
private void OnBrowserConsoleMessage(object sender, ConsoleMessageEventArgs args)
{
theMain.agregaRow(args);
}
}
And in MainForm:
private void AddInnerForm(string url)
{
var inner = new InnerForm(url, this)
// more code
}
From your code it easy to see what you're initializing theMain variable in this constructor:
public InnerForm(MainForm main)
{
theMain = main;
}
But in your code var inner = new InnerForm(url) you're using another constructor which is not initializing this variable - so theMain is left null and you're getting that exception when trying to access its method.
public InnerForm(string url)
{
InitializeComponent();
// more code
}

Get data from another form

I have a listview in my Mainform and I need to get the value in the textbox and label in the other form name Add_Order?
Add_Order add = new Add_Order();
ListViewItem item = new ListViewItem();
item.Text = add.textBox3.Text;
item.SubItems.Add(add.label6.Text);
item.SubItems.Add(add.textBox2.Text);
item.SubItems.Add(add.textBox1.Text);
item.SubItems.Add(add.textBox3.Text);
mainform.listView2.Items.Add(item);
I personally would not expose the controls in your Add_Order Form. Your calling Form should not be aware of the internals of the Add_Order Form, only its public Methods and Properties. I would make a Public Method and use that to retrieve the information you need. something like this:
Add_Order.cs
public partial class Add_Order : Form
{
public Add_Order()
{
InitializeComponent();
}
public List<string> GetData()
{
List<string> list = new List<string>();
list.Add(textBox3.Text);
list.Add(label6.Text);
list.Add(textBox2.Text);
list.Add(textBox1.Text);
return list;
}
}
MainForm
private void button1_Click(object sender, EventArgs e)
{
Add_Order add = new Add_Order();
add.ShowDialog();
ListViewItem item = new ListViewItem();
List<string> data = add.GetData();
item.Text = data[0];
item.SubItems.Add(data[1]);
item.SubItems.Add(data[2]);
item.SubItems.Add(data[3]);
item.SubItems.Add(data[0]);
listView2.Items.Add(item);
}
You can pass the data to other forms in different ways like creating public classes to maintain data common data between forms or you can pass data using form constructor like :
Add_Order frmAddOrder=new Add_Order(data1,data2);
frmAddOrder.show();
and in your Add_Order Constructor :
public Add_Order (string data1,string data2)
{
InitializeComponent();
//you can access data1 and data2 here ...
}
I write a simple one for you:
Set element Modifiers to true in Add_Order form :
and get it in main form:
public partial class main : Form
{
public main()
{
InitializeComponent();
Get_Frm2_Data();
}
private void Get_Frm2_Data()
{
Add_Order frm2 = new Add_Order();
List<string> info= new List<string>;
info.Add( frm2.textBox1.Text);
.
.
.
}
}
edit
or make an structure:
Add_Order.cs
public partial class Add_Order : Form
{
public Add_Order()
{
InitializeComponent();
}
public Info Get_Data()
{
return new Info() { _textBox3 = textBox3.Text,
_label6 = label6.Text,
_textBox2 = textBox2.Text,
_textBox1 = textBox1.Text,
};
}
}
struct Info
{
public string _textBox3;
public string _label6;
public string _textBox2;
public string _textBox1;
}
Mainform.cs
public partial class main : Form
{
public main()
{
InitializeComponent();
Get_Frm2_Data();
}
private void Get_Frm2_Data()
{
Add_Order frm2 = new Add_Order();
frm2.ShowDialog();
Info lst_data= frm2.Get_Data();
ListViewItem item = new ListViewItem();
item.Text = lst._textBox3;
item.SubItems.Add(lst._label6);
item.SubItems.Add(lst._textBox2);
item.SubItems.Add(lst._textBox1);
mainform.listView2.Items.Add(item);
}
}

Gtk# statusicon disappear

I'm having a very strange problem with statuicon.
I'm doing on a simple project to save and show some data in table, I have a mainwindow(MainWindow) where the user insert the data and then there is another window where are the data shown(SumList). Also there is a status icon which I have created by sublassing the Gtk.StatusIcon. The problem is that when I start the application and show the window that should show the data(everything works) and then close the window (no matter how) the statusIcon disappear from the panel.
Also I have found that it is cause be the length of constructor of the class SumList. If I delete some lines from there (random order) the statusicon works fine.
How can I fix this strange behavior?
EDIT #1
I try not to subclass the StatusIcon instead i have declared as static member of MainClass and now it works as it should, weird. Anyway the question is why it isn't working if the statusIcon is not declared static?
The MainClass (StatusIcon)
class MainClass : StatusIcon
{
MainWindow window;
private MainClass()
{
window = new MainWindow();
window.Show();
Stock = Gtk.Stock.Home;
PopupMenu += rightClick;
Activate += leftClick;
}
private void rightClick (object sender, Gtk.PopupMenuArgs evt){
window.Hide();
}
private void leftClick (object sender, EventArgs e){
window.Show();
}
public static void Main (string[] args)
{
Application.Init ();
new MainClass();
Application.Run ();
}
}
The SumList class
public partial class SumList : Gtk.Window
{
public SumList () : base(Gtk.WindowType.Toplevel)
{
this.Build ();
// create the "title" column ------------ //
TreeViewColumn title = new TreeViewColumn();
CellRendererText titleR = new CellRendererText();
title.PackStart(titleR, true);
title.AddAttribute(titleR, "text", 0);
// create the "detial" column ----------- //
TreeViewColumn detail = new TreeViewColumn();
CellRendererText detailR = new CellRendererText();
detail.PackStart(detailR, true);
detail.AddAttribute(detailR, "text", 1);
// create the "price" column ------------ //
TreeViewColumn price = new TreeViewColumn();
CellRendererText priceR = new CellRendererText();
price.PackStart(priceR, true);
price.AddAttribute(priceR, "text", 2);
// create the "date" column ------------- //
TreeViewColumn date = new TreeViewColumn();
CellRendererText dateR = new CellRendererText();
date.PackStart(dateR, true);
date.AddAttribute(dateR, "text", 3);
// set the columns names
title.Title = "Title";
detail.Title = "Detail";
price.Title = "Price";
date.Title = "Date";
// append columns to the treeview
this.treeview.AppendColumn(title);
this.treeview.AppendColumn(detail);
this.treeview.AppendColumn(price);
this.treeview.AppendColumn(date);
// set the model
this.treeview.Model = Singleton.Model.Instance.Data;
}
}
The MainWindow class
public partial class MainWindow: Gtk.Window{
public MainWindow (): base (Gtk.WindowType.Toplevel){
Build ();
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a){
Application.Quit ();
a.RetVal = true;
}
protected void OnButtonOKClicked (object sender, System.EventArgs e){
SumList list = new SumList();
list.Show();
}
protected void onButtonHideClicked (object sender, System.EventArgs e){
entrySum.Text = "";
entryTitle.Text = "";
this.Hide();
}
}
Simple, your GTK control is getting garbage collected.
public static void Main (string[] args)
{
Application.Init ();
new MainClass();
Application.Run ();
}
You now no longer have any live references to your MainClass instance. IMO you are lucky that the program even does this.

Categories