Selected rows of the DataGridView reset after load of dialog - c#

I have one dialog, which based on System.Windows.Forms.Form. It contains one control DataGridView.
I fill this DataGridView, and select any rows. Later call I the method ShowDialog of my form. After appear of form I can see that selected first row of DataGridView, but my desired rows are not selected. How can I resolve this problem? I want no make select in the method OnLoad
Below is my code.
DgvDataSource dgvDs = new DgvDataSource();
DgvForm dgvF = new DgvForm();
dgvF.DataSource = dgvDs;
dgvF.SelectRows(new int[] { 3, 5, 7, 9, 10}); dgvF.ShowDialog();
public class DgvForm : Form
{
public DgvForm()
{
InitializeComponent();
}
DgvDataSource dataSource;
public DgvDataSource DataSource
{
get { return myDataGridView.DataSource; }
set
{
myDataGridView.DataSource = value;
}
}
public void SelectRows(int[] indexes)
{
myDataGridView.ClearSelection();
foreach (DataGridViewRow r in dataGridView1.Rows)
{
r.Cells[0].Selected = indexes.Contains(r.Index);
}
}
}
public class DgvDataSource
{
public BindingList<DgvItem> Items { get; private set; }
public DgvDataSource()
{
InitItems();
}
void InitItems()
{
Items = new BindingList<DgvItem>();
for (int i = 0; i < 20; i++)
{
Items.Add(new DgvItem() { Id = i + 1,
Description = "Description " + (i+1).ToString() });
}
}
}
public class DgvItem
{
public int Id { get; set; }
public string Description { get; set; }
}

Put you SelectRows in the Load Event in the Dialog Form. When you create the instance, set a int[] property:
DgvForm dgvF = new DgvForm();
//this property should be in the Dialog Form
dgvF.Selection = new int[] { 3, 5, 7, 9, 10};
dgvF.ShowDialog();
Luego en el Form:
private int[] selection;
public int[] Selection
{
get { return selection; }
set { selection = value; }
}
private void Form1_Load(object sender, EventArgs e)
{
//Put your code here, to load DataSource and Select Rows.
}

Related

How to make a listbox display items from a checked list and radio buttons? - C# Windows Form

I'm doing a project where I am trying to simulate an ice cream parlor. For this specific section, I have the (mutually exclusive) radio buttons representing the dressing the customer can select. There are also a number of checked items (not mutually exclusive) which the customer can select in the checkedListBox. All of the items that a customer selects from the radio buttons and checkedListBox are supposed to appear in a listbox. so that the customer can keep track of all of the ordered items.
Of course, all of the code here is very unfinished and basic. I don't plan on adding any of the calculations for the prices until I make sure that the structure itself is working.
This is what I currently have so far:
private void GetToppings()
{
foreach (ListViewItem li in checkedListBox1.Items)
{
if (li.Selected == true)
{
label1.Text += li + " ";
}
}
if (checkedListBox1.SelectedItem.ToString() == "Sprinkles")
{
}
if (checkedListBox1.SelectedItem.ToString() == "Chocolate Chips")
{
}
if (checkedListBox1.SelectedItem.ToString() == "M&Ms")
{
}
if (checkedListBox1.SelectedItem.ToString() == "Oreos")
{
}
if (checkedListBox1.SelectedItem.ToString() == "Cookie Dough")
{
}
private void GetDressing()
{
if (radioButton1.Checked)
{
sDressing += "Caramel";
}
if (radioButton2.Checked)
{
sDressing += "Hot Fudge";
}
if (radioButton3.Checked)
{
sDressing += "Peanut Butter";
}
if (radioButton4.Checked)
{
sDressing += "Strawberry Syrup";
}
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i<18; i++)
{
listBox1.Items.Add(i);
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
listBox1.Items.Remove(listBox1.SelectedItem);
}
I am still very new to Windows Form programming in C#, so please forgive me if any of these questions/errors seem very basic.
The RadioButton use the following
var radioButton = Controls.OfType<RadioButton>().FirstOrDefault(x => x.Checked);
if (radioButton is not null)
{
// do something
}
For the CheckedListBox consider the following which populates via a model/class which has text and a identifier as in most cases at a later date you work with a data source this is important to keep track of items which you are not there yet but best to do it just the same.
Extension method to get items in the CheckedListBox. Place in a class file.
public static class CheckedListBoxExtensions
{
public static List<T> CheckedList<T>(this CheckedListBox sender)
=> sender.Items.Cast<T>()
.Where((_, index) => sender.GetItemChecked(index))
.Select(item => item)
.ToList();
}
Use a class/model for populating the CheckedListBox, ToString is used to display the item. Place in a class file.
public class Topping
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString() => Name;
}
Implementation
public partial class StackOverflowForm : Form
{
public StackOverflowForm()
{
InitializeComponent();
List<Topping> toppings = new List<Topping>
{
new Topping() { Id = 1, Name = "Sprinkles" },
new Topping() { Id = 2, Name = "Chocolate Chips" },
new Topping() { Id = 3, Name = "M&Ms" },
new Topping() { Id = 4, Name = "Oreos" },
new Topping() { Id = 5, Name = "Cookie Dough" }
};
checkedListBox1.DataSource = toppings;
}
private void GetToppingsButton_Click(object sender, EventArgs e)
{
List<Topping> toppings = checkedListBox1.CheckedList<Topping>();
if (toppings.Count > 0)
{
listBox1.DataSource = toppings;
}
else
{
listBox1.DataSource = null;
}
}
}

How to access a specific cell in a DataGridViewRow?

How can I access a specific cell by index in a DataGridViewRow?
Regular DataGridView has Rows parameter, DataGridViewRow doesn't have it
var GridRow = new DataGridViewRow();
GridRow.Cells.Add(cell1);
GridRow.Cells.Add(cell);
GridRow.Cells[1].Value = true;
I guess this is what you want to achieve?
int index = yourDGV.Rows.Add(GridRow);
//Get newly added row
var row = yourDGV.Rows[index];
//value of cell
var value = row.Cells[1].Value
It's better to strong type data in a DataGridView in tangent with utilizing a BindingSource. The BindingSource provides access to data in the DataGridView without the need to touch rows/cells in the DataGridView.
Simple example, for indexing into the data a NumericUpDown control gets the index into the data and if in range shows current data while the second method accesses the current row via BindingSource.Current property which is an object that we need to cast to the underlying type, same with the index method.
Simple model
public class Item
{
public bool Check { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
}
Form code
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace YourNamespaceGoesHere
{
public partial class ExampleForm : Form
{
private readonly BindingSource _bindingSource = new BindingSource();
public ExampleForm()
{
InitializeComponent();
_bindingSource.DataSource = new List<Item>()
{
new Item() {Check = false, Name = "Apples", Quantity = 1},
new Item() {Check = true, Name = "Oranges", Quantity = 0},
};
dataGridView1.DataSource = _bindingSource;
}
private void ByIndexButton_Click(object sender, EventArgs e)
{
int index = (int)numericUpDown1.Value;
if (index <= _bindingSource.Count -1)
{
var item = (Item)_bindingSource[index];
MessageBox.Show($"{(item.Check ? "Yes" : "No"),-5}{item.Name}{item.Quantity,4}");
}
else
{
MessageBox.Show($"{index} is out of range");
}
}
private void CurrentButton_Click(object sender, EventArgs e)
{
if (_bindingSource.Current != null)
{
var item = (Item)_bindingSource.Current;
MessageBox.Show($"{(item.Check ? "Yes" : "No"), -5}{item.Name}{item.Quantity,4}");
}
}
}
}

updat a Variable by change the checked Items in checkedlistBox C'

I have two Forms the First Form has an Array Variable and in the seconf Form there is CheckedlistBox.
public partial class FormDiagramm : Form{
DiagramAuswählen DA= new DiagramAuswählen();
int c =DA.i_wahl[0]
int c1 =DA.i_wahl[1]
int c2 =DA.i_wahl[2]
int c3 =DA.i_wahl[3]}
how can I change the Value of i_wahl[0],i_wahl[1],i_wahl[2] and i_wahl[3].
by changing the checked Items in the checkedlist box
public partial class DiagrammAuswählen : Form
{
public int[] i_wahl = new int[4];
public void CLB_Spannung_ItemCheck(object sender, ItemCheckEventArgs e)
{
if(e.NewValue == CheckState.Checked)
{
dd();
}
}
public void dd()
{
int index_1 = 0;
i_wahl[0] = 0;
i_wahl[1] = 1;
i_wahl[2] = 2;
i_wahl[3] = 3;
for (int index = 0; index < 19; index++)
{
if (CLB_Spannung.GetItemCheckState(index) == CheckState.Checked)
{
i_wahl[index_1] = index;
index_1++;
if (index_1 > 3)
{
goto End_Wahl;
}
}
}
End_Wahl:;
}
How could I do this??
Make a new project with two forms. Form1 shall have 1 button. Form2 shall have 1 datagridview
Form1.cs
namespace Whatever
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var ps = new List<Person>()
{
new Person(){ Active = true, FirstName = "John" },
new Person(){ Active = false, FirstName = "Jane" },
};
new Form2(ps).ShowDialog();
foreach (var p in ps)
MessageBox.Show($"{p.FirstName} is {p.Active}");
}
}
public class Person
{
public bool Active { get; set; }
public string FirstName { get; set; }
}
}
Form2.cs
namespace WinFormsApp472
{
public partial class Form2 : Form
{
public Form2(List<Person> x)
{
InitializeComponent();
dataGridView1.DataSource = x;
}
}
}
I would put some words of explanation in, but there isn't really a lot to explain; Form2 accepts list via constructor, binds it to grid. Grid can be used to alter choices. Upon close, MessageBoxes prove Form1 has altered values

Insert specific elements in ASP:GridView

I have some problem with GridView component. My task is to insert into the gridview data from a class called a book whose number of pages is greater than 100. Class:
public class Knjiga {
public string nazivKnjige { get; set; }
public string imeAutora { get; set; }
public int brStr { get; set; }
public int ID { get; set; }
public Knjiga(string naziv, string ime, int broj, int id) {
nazivKnjige = naziv;
imeAutora = ime;
brStr = broj;
ID = id;
}
}
I try something like this:
List<Knjiga> biblioteka = new List<Knjiga>() {
new Knjiga("Mali Princ", "Hans Kristiansen Andersen", 355, 009),
new Knjiga("Na Drini cuprija", "Ivo Andric", 100, 088),
new Knjiga("Starac i more", "Ernest Hemingvej", 67, 033),
new Knjiga("Covek posle rata", "Dusan Vasiljev", 255, 011),
new Knjiga("Gradinar", "Rabindranat Tagore", 125, 077)
};
protected void GridView1_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
{
for (int i = 0; i < biblioteka.Count; i++)
{
if (biblioteka[i].brStr > 100)
{
GridView1.DataSource = biblioteka;
GridView1.DataBind();
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < biblioteka.Count; i++)
{
if (biblioteka[i].brStr > 100)
{
GridView1.DataSource = biblioteka;
GridView1.DataBind();
}
}
}
But when I start a project, all the data is inserted into the gridview, regardless of whether its number of pages exceeds 100. Does anyone know how to insert only those objects where the number of pages is greater than 100 ??
Before binding the data, to grid view, prepare the data source based on your business.
You are binding the same data multiple times, as the data binding logic present in for-loop

linking multiple listboxes c#

I'm trying to create a listbox with categories and another listbox for items in each category. I want to be able to select a category in the first listbox and then the second listbox will change to display the items for that particular category. Its very common and I'm sure you can understand what I mean here. I was looking around for it but couldn't get any idea how to do this. I've created 2 listboxes for the moment and the values I want in it, thats it. any help?
I created a winform with two list boxes listbox1 and listbox2 and this is what my Form1.cs looks like
namespace WinFormsApp
{
public partial class Form1 : Form
{
private List<Category> categories;
public Form1()
{
InitializeComponent();
categories = new List<Category>();
var categoryOne = new Category { Name = "Category 1"} ;
categoryOne.Items.Add( new CategoryItem { Name = "Item 1"} );
var categoryTwo = new Category { Name = "Category 2" };
categoryTwo.Items.Add( new CategoryItem { Name = "Item 2" } );
categories.Add( categoryOne );
categories.Add( categoryTwo );
}
private void Form1_Load(object sender, System.EventArgs e)
{
categoryBindingSource.DataSource = categories;
}
}
public class Category
{
public string Name { get; set; }
public List<CategoryItem> Items { get; private set; }
public Category()
{
Items = new List<CategoryItem>();
}
}
public class CategoryItem
{
public string Name { get; set; }
}
}
and here is the InitializeComponent() code
this.listBox1.DataSource = this.categoryBindingSource;
this.listBox1.DisplayMember = "Name";
this.listBox1.FormattingEnabled = true;
this.listBox1.Location = new System.Drawing.Point(24, 24);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(242, 238);
this.listBox1.TabIndex = 0;
this.listBox1.ValueMember = "Items";
this.categoryBindingSource.DataSource = typeof(Category);
this.listBox2.DataSource = this.itemsBindingSource;
this.listBox2.FormattingEnabled = true;
this.listBox2.Location = new System.Drawing.Point(286, 24);
this.listBox2.Name = "listBox2";
this.listBox2.Size = new System.Drawing.Size(276, 238);
this.listBox2.TabIndex = 1;
this.listBox2.ValueMember = "Name";
this.itemsBindingSource.DataMember = "Items";
this.itemsBindingSource.DataSource = this.categoryBindingSource;
Working example (simplified):
private class CategoryItems
{
public string Category { get; set; }
public string Item { get; set; }
public CategoryItems(string category, string item)
{
this.Category = category;
this.Item = item;
}
public override string ToString()
{
return this.Item;
}
}
private List<string> categories = new List<string>();
private List<CategoryItems> catItems = new List<CategoryItems>();
private void Form1_Load(object sender, EventArgs e)
{
categories.Add("Cat 1");
categories.Add("Cat 2");
catItems.Add(new CategoryItems("Cat 1", "Cat 1 Item 1"));
catItems.Add(new CategoryItems("Cat 1", "Cat 1 Item 2"));
catItems.Add(new CategoryItems("Cat 2", "Cat 2 Item 1"));
catItems.Add(new CategoryItems("Cat 2", "Cat 2 Item 2"));
foreach (string cat in categories)
{
listBox1.Items.Add(cat);
}
listBox1.SelectedIndexChanged += new EventHandler(listBox1_SelectedIndexChanged);
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
listBox2.Items.Clear();
foreach (CategoryItems ci in catItems)
{
if (ci.Category == listBox1.SelectedItem.ToString())
listBox2.Items.Add(ci);
}
}
Have a function that fills the second listbox based on the contents of the first.
Add an event for when the first listbox changes, and call the funcion described in #1

Categories