Two conditions checking on listview group items - c#

I have list view (with one column). I have divided this list view into two groups like in the figure below.
My problem is: how can I find selection event like this: If I click on odd group item ("one") and then if I click on even group item ("two"), I want to do something.
How can I check these two conditions in a single if statement? These two conditions are the ones that need to be done in a single if statement. Is it possible to use a single condition?
I am using C# and WinForms apps. Would anyone please help on this?
EDIT :
Category names
name 1
name 2
name 3
prices
>100
>200
300+
If I click on category name and then I click on the price range, I want to do something. Is it possible to do both in single condition checking?

Try using the SelectedIndexChanged event like so:
void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
var selectedItems = listView1.SelectedItems.Cast<ListViewItem>();
var passed = (selectedItems.Select(l => l.Group.Name).Distinct().Count() == 2 && selectedItems.Count() == 2);
if (passed)
{
//Do something...
}
}
Edit (based on comments)
To retrieve each selected item use the following:
Note: For the below code to work you would need to set the Name property of each of your ListViewGroup's to "Category" and "Prices" respectively.
void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
var selectedItems = listView1.SelectedItems.Cast<ListViewItem>();
var passed = (selectedItems.Select(l => l.Group.Name).Distinct().Count() == 2 && selectedItems.Count() == 2);
if (passed)
{
var categoryItem = selectedItems.Where(l => l.Group.Name.ToLower() == "category").Single();
var priceItem = selectedItems.Where(l => l.Group.Name.ToLower() == "prices").Single();
}
}

Related

What is a good substitute for an if else if in ComboBox?

I need to develop a Employee Payroll Computation for my exam.
I have successfully entered a code for when the Employee Number is chosen, there is a list of 1,2,3,4,5 and every number, a name appears on the Employee Name. I would like to know if there is another way to code it?
if (cmbEmployeeNum.SelectedIndex == 0)
{
txtEmployeeName.Text = "Sheldon Cooper";
}
else if (cmbEmployeeNum.SelectedIndex == 1)
{
txtEmployeeName.Text = "Leonard Hofstadter";
}
else if (cmbEmployeeNum.SelectedIndex == 2)
{
txtEmployeeName.Text = "Howard Wolowitz";
}
else if (cmbEmployeeNum.SelectedIndex == 3)
{
txtEmployeeName.Text = "Raj Koothrappali";
}
else
{
txtEmployeeName.Text = "Penny";
}
Also, Position Code is also in ComboBox. Do I only use the same code style because in position code, there is A, B, C and every code has an equivalent rate per day.
My teacher gave this final exam to us but he didn't really teach us the other lessons.
Actually, if you're going to use the event of the ComboBox called SelectedIndexChanged, you don't have to use conditional statement to show all those names on your textbox.
You can store the names in an array and call those depends on the SelectedIndex of the combobox like below code:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string[] names = { "Sheldon Cooper", "Leonard Hofstadter", "Howard Wolowitz" };
txtEmployeeName.Text = names[comboBox1.SelectedIndex];
}

c# how to avoid adding the same product id from textbox.text to listbox

I have a code here that tells you that, for every product in a bound list called product of a ProductListSource.DataSource, I have an if statement that if the product.ProdID is equal to the text you have inputted, you should add that on to a listbox. But the problem is I want a limiter... I don't want the same id to be added more than one.
Here's my code demonstrating what I have done so far:
private void AddToCartButton_Click(object sender, EventArgs e)
{
foreach (var product in (BindingList<Product>) ProductListSource.DataSource)
{
if (product.ProdID == ProdIDText.Text.Trim())
{
CartList.Items.Add(product);
}
}
}
You can use the Distinct LINQ extension method to filter products with common product IDs:
var productList = (BindingList<Product>)ProductListSource.DataSource;
foreach (var product in productList.Distinct((one, two) => one.ProdID == two.ProdID))
{
if (product.ProdID == ProdIDText.Text.Trim())
{
CartList.Items.Add(product);
}
}

Sorting a ListView by tag in C#

I have a list view with some columns listViewItems. When I use the Sort method listViewItems.Sort(); it sorts by column text by default. This is the code I use:
private void OnColumnClick(object sender, ColumnClickEventArgs e)
{
int sortColumn = 0; --I only want to sort if you click this column header, not others
if (e.Column == sortColumn)
{
if (listViewItems.Sorting == SortOrder.Ascending)
{
listViewItems.Sorting = SortOrder.Descending;
}
else
{
listViewItems.Sorting = SortOrder.Ascending;
}
}
listViewItems.Sort();
However, my items have a Tag, accessible by listViewItems[0].Tag;
I would like to use that tag to sort the list (in my case tag is an int), but I don't know how to do it nor find information about something similar. Sort method doesn't accept any parameters. I tried to create a column sorter, but it also expects a column.
ListViewColumnSorter lvwColumnSorter;
lvwColumnSorter = new ListViewColumnSorter();
listViewItems.ListViewItemSorter = lvwColumnSorter;
lvwColumnSorter.SortColumn = ?;
Any ideas?
Thanks in advance.
var items = ListView.Items.Cast<ListViewItem>().OrderBy(x => x.Tag).ToList();
ListView.Items.Clear();
ListView.Items.AddRange(items.ToArray());

Display item value to specific datagridcolumn selected from datagridcomboboxcolumn and dynamically compute for the total for each selection

I am developing windows form using c# and using datagridview object. I am almost done but I have a problem with displaying item value to a specific column(PTS GAIN COLUMN) that I selected in a comboboxcell all inside datagridview. Data is selected from database(coded). The column(PTS GAIN COLUMN) where I want to display the selected item value has no entry in the database. It is empty. I want that every time I select a item from a comboboxcell per row is that it will display the value to a specific column(PTS GAIN COLUMN) and compute the total dynamically/real-time(I want to show the result in label.text)
Also the combobox cell has items YES,NO,NA(this has no datatable, I just added the items by coding combobox.items.add("yes/no/na"). Yes item will get value depending on the column PTS AVAIL and display on column PTS GAIN. If I select no, 0 will display in PTS GAIN column, and if NA, both PTS AVAIL and PTS GAIN will have 0. Again I want to if possible to compute the total real-time.
Any help with this matter is much appreciated. I am meeting a dead line so please, anyone! Have a great day! Btw, I will post screenshot of the program, and if you want to see a particular block of code for reference just comment.
You will need to hook up with 2 events to accomplish this but for the most part it is pretty easy.
private void MyInitializeComponent()
{
dg.CurrentCellDirtyStateChanged += Dg_CurrentCellDirtyStateChanged;
dg.CellValueChanged += Dg_CellValueChanged;
this.CalculateTotals();
}
private void Dg_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (dg.Columns[e.ColumnIndex].Name == "Choices")
{
switch (dg.Rows[e.RowIndex].Cells["Choices"].Value.ToString())
{
case ("Yes"):
{
dg.Rows[e.RowIndex].Cells["PointsGained"].Value =
dg.Rows[dg.CurrentCell.RowIndex].Cells["PointsAvailable"].Value;
break;
}
case ("No"):
{
dg.Rows[e.RowIndex].Cells["PointsGained"].Value = 0;
break;
}
case ("NA"):
{
dg.Rows[e.RowIndex].Cells["PointsGained"].Value = "NA";
break;
}
}
this.CalculateTotals();
}
}
private void Dg_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if ((dg.Columns[dg.CurrentCell.ColumnIndex].Name == "Choices") &&
(dg.IsCurrentCellDirty))
{
dg.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
private void CalculateTotals()
{
var totalPointsGained = dg.Rows.Cast<DataGridViewRow>()
.Where(a => a.Cells["PointsGained"].Value?.ToString() != "NA")
.Sum(a => Convert.ToInt32(a.Cells["PointsGained"].Value));
var totalPointsAvailable = dg.Rows.Cast<DataGridViewRow>()
.Where(a => a.Cells["PointsAvailable"].Value?.ToString() != "NA")
.Sum(a => Convert.ToInt32(a.Cells["PointsAvailable"].Value));
lblTotalPointsGained.Text = "Total Points Gained: " + totalPointsGained;
lblTotalAvailable.Text = "Total Points Available: " + totalPointsAvailable;
}
You can put the code I have in MyInitializeComponent() wherever you initialize your other objects on the form.

Create binding in code from xml data

I want to bind data from sample data to code in c#. I am not getting exact output when tried different models available online. I want to do arithmetic operation between two values from data table.
My xml data looks like this:
<SampleData:data xmlns:SampleData="clr-namespace:Expression.Blend.SampleData.data"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<SampleData:data.factors>
<SampleData:cfsItem col1="item1" item1="1" item2="2" />
<SampleData:cfsItem col2="item2" item2="3" item2="4" />
</SampleData:data.factors>
</SampleData:data>
I want to select the value with a LINQ query; i.e selecting col1 from table 'factors' in data and compare it with value returned from listbox element.
private void ListBox1_Tap(object sender, GestureEventArgs e)
{
ListBoxItem selected = ListBox1.SelectedItem as ListBoxItem;
string y = selected.Content as string;
this.DataContext = from factors in data
where col1.factors == y
select item1;
}
Can anyone help me out of this? Thank you!
It looks like your data object is a single item and that you're really looking for factors inside data.Based on what you show you would probably need the following to select the factors based on the ListBox.SelectedItem's content compared to the col1 property.
Just as a note: I think you meant the first item2 in the second record to really mean item1. If so the following would apply:
private void ListBox1_Tap(object sender, GestureEventArgs e)
{
var selectedItem = (ListBoxItem)ListBox1.SelectedItem;
if (selectedItem != null)
{
var y = (string)selectedItem.Content;
var filteredFactors = (from factor in data.factors
where factor.col1 == y
select factor.Item1);
//filteredFactors is IEnumerable
this.DataContext = filteredFactors;
// if you need the first only or nothing if there is none.
this.DataContext = filteredFactors.FirstOrDefault();
// if there can be nothing or only one
this.DataContext = filteredFactors.SingleOrDefault();
}
}
In the example above I selected only item1 of the filtered factors.
If you want to return the entire record you would remove .item1 in the query.
var filteredFactors = (from factor in data.factors
where factor.col1 == y
select factor);
You'll probably notice I have used the keyword var multiple times. I like to use it if it improves readability. see Implicitly Typed Local Variables if you're interested.

Categories