wpf get value by name? - c#

on WPF on c# i have combobox
<ComboBox x:Name="listCombobox" />
and i add it item like
var list = new[]
{
new { Number = 1, Name = "Smith" },
new { Number = 12, Name = "John" } ,
new { Number = 14, Name = "Bon" }
}.ToList();
foreach (var item in list)
{
listCombobox.Items.Add(item.Name);
}
what i want that on the combobox i will see the Name(like now)
but when i selected , on the code behind i will see not the name i selected
i want to see the Number that selected
thanks!

Define a class like this
public class dataObject
{
public int Number { get; set; }
public string Name { get; set; }
}
And fill the data,
List<dataObject> bindingList = new List<dataObject>();
bindingList.Add(new dataObject()
{
Name = "Smith",
Number = 1
});
bindingList.Add(new dataObject()
{
Name = "John",
Number = 12
});
bindingList.Add(new dataObject()
{
Name = "Bon",
Number = 14
});
listCombobox.ItemsSource = bindingList;
listCombobox.DisplayMemberPath = "Name";
On selectionChanged event of the combobox, do this,
private void listCombobox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
dataObject result = (dataObject)listCombobox.SelectedItem;
var selectedNumber = result.Number;
}

I would use a custom ListItem class and assign objects of this type to the ItemSource property of the combobox control like this:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var list = new List<ListItem>
{
new ListItem{ Value = 1, Text = "Smith" },
new ListItem{ Value = 12, Text = "John" } ,
new ListItem{ Value = 14, Text = "Bon" }
}.ToList();
listCombobox.ItemsSource = list;
listCombobox.DisplayMemberPath = "Text";
listCombobox.SelectedValuePath = "Value";
}
private void listCombobox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedItem = (sender as ComboBox).SelectedItem as ListItem;
if (selectedItem != null)
{
// do something with the selected item
}
}
}
public class ListItem
{
public string Text { get; set; }
public int Value { get; set; }
}

I would solve it as follows:
...
foreach (var item in list)
listCombobox.Items.Add(new ComboBoxItem() {
Content = item.Name,
Tag = item.Number
});
You can of course retrieve your Data by using
int mytag = listCombobox.Items[3].Tag;
or
int seletected = listCombobox.SelectedItem.Tag;
MSDN Reference for PresentationFramework.dll::System.Windows.Frameworkelement.Tag

Easiest way, I think, is to put these numbers as Tag of every listCombobox item:
foreach (var item in list) {
listCombobox.Items.Add(new ComboBoxItem { Content = item.Name, Tag = item.Number });
}
And access your number (OnSelectedItemchanged, for example):
void Cb_SelectionChanged(object sender, SelectionChangedEventArgs e) {
int number = (int)((ComboBoxItem) listCombobox.SelectedItem).Tag;
}

Related

Duplicate Result When Trying To Fill Datagridview From Checklistbox With ValueMember And DisplayMember

why this loop Return A Duplicate Result
Duplicate Result When Trying To Fill Datagridview From Checklistbox With ValueMember And DisplayMember
private void btn_ShowDetails_Click(object sender, EventArgs e)
{
for (int i = 0; i < clb_SubItems.Items.Count; i++)
{
if (clb_SubItems.GetItemChecked(i))
{
foreach (var item in clb_SubItems.CheckedItems.OfType<SP_SelectDriverItem_Result>())
{
dgv_BOQItems.Rows.Add(item.SubCostItemID, clb_SubItems.GetItemText(clb_SubItems.Items[i]));
}
}
}
}
You might consider setting up the DataGridView with a preset columns and set the DataSource to a List.
Example
Backing class, ToString will be the DisplayMember of the CheckedListBox.
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString() => Name;
}
Mocked data
public class Mocked
{
public static List<Company> Companies => new List<Company>()
{
new Company() {Id = 1, Name = "A"},
new Company() {Id = 2, Name = "B"},
new Company() {Id = 3, Name = "C"},
new Company() {Id = 4, Name = "D"},
};
}
Extension method to get checked companies in a CheckedListBox
public static class CheckedListBoxExtensions
{
public static List<T> CheckedList<T>(this CheckedListBox source)
=> source.Items.Cast<T>()
.Where((item, index) => source.GetItemChecked(index))
.Select(item => item)
.ToList();
}
Form
One CheckedListBox
One DataGridView with columns setup for Id and Name in Company class
One button to get checked items and add each one if not currently in the DataGridView.
Code
public partial class Form1 : Form
{
private readonly BindingSource bindingSource = new BindingSource();
protected BindingList<Company> bindingList = new BindingList<Company>();
public Form1()
{
InitializeComponent();
dataGridView1.AutoGenerateColumns = false;
}
private void Form1_Load(object sender, EventArgs e)
{
bindingSource.DataSource = bindingList;
dataGridView1.DataSource = bindingSource;
checkedListBox1.DataSource = Mocked.Companies;
}
private void PopulateGridButton_Click(object sender, EventArgs e)
{
var result = checkedListBox1.CheckedList<Company>();
if (result.Count <= 0) return;
foreach (var company in result)
{
if (!bindingList.Contains(company))
{
bindingList.Add(company);
}
}
}
}

datagridview in winform, columncombobox value change

I am designing a winform in which I have a datagridview with predefined columns, the first column is a combobox and rest 3 columns are textboxes.
I am not binding datagridview to any datasource since the user is going to fill the last column "Qty", all I want to achieve is, when user clicks on the combobox it should show 3 columns from the database table (item code, item name and uom) and when user select any particular "item code" corresponding "item name" and "uom" should be displayed in second column and third column of the datagridview. Likewise the user should be able to enter as many row as he require. After data entry the data will be saved in a table named "purchase requisition".
I have not done any coding so far and have designed only the form.
See if the following will provide base code to roll with. There are several classes to mock up data and a extension method which should be move to own files.
DataGridView was not configured in the designer, just in code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace UnboundDataGridViewComboBox
{
public partial class Form1 : Form
{
private ComboBox _cbo;
private string _comboColumnName = "ItemCodeColumn";
private List<Item> _items => Mocked.Items;
public Form1()
{
InitializeComponent();
Shown += OnShown;
}
private void OnShown(object sender, EventArgs e)
{
var column1 = new DataGridViewComboBoxColumn
{
DataSource = _items.Select(x => x.ItemCode).ToArray(),
DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing,
Name = _comboColumnName,
HeaderText = "Item Code",
SortMode = DataGridViewColumnSortMode.NotSortable
};
var column2 = new DataGridViewTextBoxColumn
{
Name = "ItemNameColumn",
HeaderText = "Item Name"
};
var column3 = new DataGridViewTextBoxColumn
{
Name = "UomColumn",
HeaderText = "UOM"
};
var column4 = new DataGridViewTextBoxColumn
{
Name = "QuanityColumn",
HeaderText = "Quanity"
};
ItemsDataGridView.Columns.AddRange(column1, column2, column3, column4);
ItemsDataGridView.EditingControlShowing += DataGridView1OnEditingControlShowing;
}
private void DataGridView1OnEditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (!ItemsDataGridView.CurrentCell.IsComboBoxCell()) return;
if (ItemsDataGridView.Columns[ItemsDataGridView.CurrentCell.ColumnIndex].Name != _comboColumnName) return;
_cbo = e.Control as ComboBox;
_cbo.SelectedIndexChanged -= ItemCodeColumnComboSelectionChanged;
_cbo.SelectedIndexChanged += ItemCodeColumnComboSelectionChanged;
}
private void ItemCodeColumnComboSelectionChanged(object sender, EventArgs e)
{
DataGridViewComboBoxEditingControl control = sender as DataGridViewComboBoxEditingControl;
Item item = _items.FirstOrDefault(x => x.ItemCode == control.EditingControlFormattedValue.ToString());
if (item == null)
{
return;
}
ItemsDataGridView.CurrentRow.Cells[1].Value = item.Name;
ItemsDataGridView.CurrentRow.Cells[2].Value = item.UOM;
}
}
#region Place classes into their own files
public static class Extensions
{
public static bool IsComboBoxCell(this DataGridViewCell sender)
=> sender.EditType != null &&
sender.EditType == typeof(DataGridViewComboBoxEditingControl);
}
// represents a table in a database
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public string ItemCode { get; set; }
public string UOM { get; set; }
public override string ToString() => ItemCode;
}
class Mocked
{
// simulate data from database
public static List<Item> Items => new List<Item>()
{
new Item() {Id = 1,Name = "P1", ItemCode = "A100", UOM = "Q1"},
new Item() {Id = 2,Name = "P2", ItemCode = "A200", UOM = "W1"},
new Item() {Id = 3,Name = "P3", ItemCode = "A300", UOM = "B1"},
new Item() {Id = 4,Name = "P4", ItemCode = "A400", UOM = "H1"}
};
}
#endregion
}

adding data to dataset

I have a dataset created in "visual studio".
when i open for with data grid it fills the data grid and i can see the data i have entered.
whan loading the form again the data is gone
I have used this code to create new data row.
foreach (var ticket in esTicket)
{
databaseDataSet1.ES.AddESRow(ticket.esNum, ticket.title, ticket.link, ticket.open, ticket.escalated, ticket.downTime, ticket.startWork, ticket.endWork, ticket.toolID, ticket.toolType, ticket.openedBy);
}
and also:
foreach (var ticket in esTicket)
{
databaseDataSet1.ES.Rows.Add(ticket.esNum, ticket.title, ticket.link, ticket.open, ticket.escalated, ticket.downTime, ticket.startWork, ticket.endWork, ticket.toolID, ticket.toolType, ticket.openedBy);
}
the inserted data just does not show
It seems that your esTicket is a list. If so, I suggest that you could use another way to fill the datagridview without using dataset.
Code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
List<Student> list = new List<Student>();
list.Add(new Student { Age=12,Name="Test1",Title="Hello" });
list.Add(new Student { Age = 13, Name = "Test2", Title = "Hi" });
list.Add(new Student { Age = 15, Name = "Test5", Title = "Greeting" });
dataGridView1.DataSource = list;
}
private void button1_Click(object sender, EventArgs e)
{
List<Student> list = (List<Student>)dataGridView1.DataSource;
list.Add(new Student { Age = 16, Name = "Test6", Title = "Hello1" });
dataGridView1.DataSource = null;
dataGridView1.DataSource = list;
}
}
public class Student
{
public int Age { get; set; }
public string Name { get; set; }
public string Title { get; set; }
}
Result:

ViewModel replacement for complex Anonymous Object

So im working with this complex anonymous object
var result = new
{
percentage = "hide",
bullets = (string)null,
item = new [] {
new {
value = 16,
text = "Day",
prefix = (string)null,
label = (string)null
},
new {
value = 41,
text = "Week",
prefix = (string)null,
label = (string)null
},
new {
value = 366,
text = "Month",
prefix = (string)null,
label = (string)null
}
}
};
And I want to convert it into a ViewModel and return it as JSON from a rest API.
What I would like to know is
How do I represent this as a model including the array item entries
How do I then add array items to the array once an instance of the model is created
Does the model need a constructor to initialize the array.
Any help or examples you could provide would be great.
Create a class with the structure:
public class Result
{
public Result()
{
// initialize collection
Items = new List<Item>();
}
public string Percentage { get; set; }
public string Bullets { get; set; }
public IList<Item> Items { get; set; }
}
public class Item
{
public int Value { get; set; }
public string Text { get; set; }
public string Prefix { get; set; }
public string Label { get; set; }
}
Then change your code to this:
var result = new Result
{
Percentage = "hide",
Bullets = (string)null,
Items = {
new Item {
Value = 16,
Text = "Day",
Prefix = (string)null,
Label = (string)null
},
new Item {
Value = 41,
Text = "Week",
Prefix = (string)null,
Label = (string)null
},
new Item {
Value = 366,
Text = "Month",
Prefix = (string)null,
Label = (string)null
}
}
};
Addressed above with the structure.
Add to collection as follows:
result.Items.Add(new Item {
Value = 367,
Text = "Month",
Prefix = (string)null,
Label = (string)null
});
I would initialize the collection in the constructor as above.
To return the json from your controller action add the following:
return Json(result, JsonRequestBehavior.AllowGet);

How to allow user to change list box order

I am looking for help, I have two lists that both add data to the same list box and it displays them as a summary, I would like to know how to let the user move an index up or down in the list box.
Items are added here
private void BtnAddpickup_Click(object sender, EventArgs e)
{
/*
* This method creates a new pickup object, allows the user to
* enter details and adds it to the List
*
*/
Pickupform.pickup = new Pickups();
//New Visit- note added to the pickupform object
Pickupform.ShowDialog();
//Show the pickupForm. ShowDialog ensures that the form has the exclusive focus until it is closed.
if (Pickupform.pickup != null)
//if null then the "cancel" button was pressed
{
Pickups newpic = Pickupform.pickup;
//Get the Pickup object from the form
thePickup.addPickups(newpic);
//Add the visit to the list
}
updateList();
//Update the list object to reflect the Pickups in the list
}
and this
public Pickups getPickups(int index)
{
//Return the pickup object at the <index> place in the list
int count = 0;
foreach (Pickups pic in pickups)
{
//Go through all the pickup objects
if (index == count)
//If we're at the correct point in the list...
return pic;
//exit this method and return the current visit
count++;
//Keep counting
}
return null;
//Return null if an index was entered that could not be found
}
This is the same for my other class, So any help would be appreciated
You can try something like this. The following code assumes a Windows form containing a ListBox named mainListBox, a button named upButton, and a button named downButton.
public partial class Form1 : Form
{
private class Person
{
public string LastName { get; set; }
public string FirstName { get; set; }
public override string ToString()
{
return string.Format("{0}, {1}", LastName, FirstName);
}
}
public Form1()
{
this.InitializeComponent();
this.mainListBox.SelectionMode = SelectionMode.One;
this.PopulateListBox();
}
private void PopulateListBox()
{
this.mainListBox.Items.Add(new Person() { FirstName = "Joe", LastName = "Smith" });
this.mainListBox.Items.Add(new Person() { FirstName = "Sally", LastName = "Jones" });
this.mainListBox.Items.Add(new Person() { FirstName = "Billy", LastName = "Anderson" });
}
private void upButton_Click(object sender, EventArgs e)
{
if (this.mainListBox.SelectedIndex > 0)
{
int selectedIndex = this.mainListBox.SelectedIndex;
object selectedItem = this.mainListBox.SelectedItem;
this.mainListBox.Items.RemoveAt(selectedIndex);
this.mainListBox.Items.Insert(selectedIndex - 1, selectedItem);
this.mainListBox.SelectedIndex = selectedIndex - 1;
}
}
private void downButton_Click(object sender, EventArgs e)
{
if (this.mainListBox.SelectedIndex > -1 &&
this.mainListBox.SelectedIndex < this.mainListBox.Items.Count - 1)
{
int selectedIndex = this.mainListBox.SelectedIndex;
object selectedItem = this.mainListBox.SelectedItem;
this.mainListBox.Items.RemoveAt(selectedIndex);
this.mainListBox.Items.Insert(selectedIndex + 1, selectedItem);
this.mainListBox.SelectedIndex = selectedIndex + 1;
}
}
}
This will only work if you are adding items to the ListBox using the ObjectCollection.Add method. If you are data binding, you can update the actual data source and use the ListBox's BindingContext to refresh.
private List<Person> people = new List<Person>();
private void PopulateListBox()
{
this.people.Add(new Person() { FirstName = "Joe", LastName = "Smith" });
this.people.Add(new Person() { FirstName = "Sally", LastName = "Jones" });
this.people.Add(new Person() { FirstName = "Billy", LastName = "Anderson" });
this.mainListBox.DataSource = people;
}
private void upButton_Click(object sender, EventArgs e)
{
if (this.mainListBox.SelectedIndex > 0)
{
int selectedIndex = this.mainListBox.SelectedIndex;
Person selectedItem = this.mainListBox.SelectedItem as Person;
this.people.RemoveAt(selectedIndex);
this.people.Insert(selectedIndex - 1, selectedItem);
this.mainListBox.SelectedIndex = selectedIndex - 1;
this.RefreshListSource();
}
}
private void RefreshListSource()
{
CurrencyManager boundList = this.mainListBox.BindingContext[this.people] as CurrencyManager;
boundList.Refresh();
}

Categories

Resources