In windows form, It has a ComboBox, Which have data binded by the DataSource.
When going to set the text property for a ComboBox.
Selected ComboBox -> Property -> Text : "--Select--".
Design page shows the given text. But when run the application the given text disappeard and the initial index value of a comboBox item appeared, Which is from the DataSource.
So i gave the ComboBox text in the Form load. I mean in the Constructor
public myform()
{
InitializeComponent();
ComboBox.Text="--Select--";
}
link revised and more. But ..
Setting default item in combo box
https://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.text(v=vs.110).aspx
Searched lot of question in SO depends to ComboBox. But those never solve my case
Edited
In that combobox, Click the right top corner , From that i choosed data for my combobox by using Datasouce. I didn't write any code for add items into combobox.
You can do something like this:
public myform()
{
InitializeComponent(); // this will be called in ComboBox ComboBox = new System.Windows.Forms.ComboBox();
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'myDataSet.someTable' table. You can move, or remove it, as needed.
this.myTableAdapter.Fill(this.myDataSet.someTable);
comboBox1.SelectedItem = null;
comboBox1.SelectedText = "--select--";
}
Suppose you bound your combobox to a List<Person>
List<Person> pp = new List<Person>();
pp.Add(new Person() {id = 1, name="Steve"});
pp.Add(new Person() {id = 2, name="Mark"});
pp.Add(new Person() {id = 3, name="Charles"});
cbo1.DisplayMember = "name";
cbo1.ValueMember = "id";
cbo1.DataSource = pp;
At this point you cannot set the Text property as you like, but instead you need to add an item to your list before setting the datasource
pp.Insert(0, new Person() {id=-1, name="--SELECT--"});
cbo1.DisplayMember = "name";
cbo1.ValueMember = "id";
cbo1.DataSource = pp;
cbo1.SelectedIndex = 0;
Of course this means that you need to add a checking code when you try to use the info from the combobox
if(cbo1.SelectedValue != null && Convert.ToInt32(cbo1.SelectedValue) == -1)
MessageBox.Show("Please select a person name");
else
......
The code is the same if you use a DataTable instead of a list. You need to add a fake row at the first position of the Rows collection of the datatable and set the initial index of the combobox to make things clear. The only thing you need to look at are the name of the datatable columns and which columns should contain a non null value before adding the row to the collection
In a table with three columns like ID, FirstName, LastName with ID,FirstName and LastName required you need to
DataRow row = datatable.NewRow();
row["ID"] = -1;
row["FirstName"] = "--Select--";
row["LastName"] = "FakeAddress";
dataTable.Rows.InsertAt(row, 0);
Related
When I was working on one of my projects I was trying to write to a datasourced combobox and then write a value into the combobox like below:
//Create list for combobox
List<string> companyList= new List<string>() { "", "Company1", "Company2" };
//Datsource list to combobox
cbCompanyName.DataSource = companyList;
//If form is set to import data and the billing address is not null
if (importAddress && StaticValues.billAddress != null)
{
//Fill all fields with data from Static Values class
cbCompanyName.Text = StaticValues.billAddress.CompanyName;
cbCountry.Text = StaticValues.billAddress.Country;
}
else
{
//Set country to US
cbCountry.SelectedIndex = 0;
}
however the line cbCompanyName.Text = StaticValues.billAddress.CompanyName; ran without writing any text to the combobox, until I set the selected index of the combobox to -1. What does setting the combobox selected index to -1 do that would change this as apposed to setting the selected index to 0?
Setting the SelectedIndex on a ComboBox to -1 deselects (SelectedItem is NULL). Setting to 0 selects the first item in Items
Combobox needs to know what is my value and display member,
giving the datasource is not enough for it.
I think you can use like this or
// comboBox.DisplayMember = "Text";
// comboBox.ValueMember = "Value";
int =0;
companyList.forEach(x=> comboBox.Items.Add(new { Text = x.toString(), Value =i++ }));
comboBox1.SelectedIndex = 0;
you can look this article
similar question and answers
I have a DataGridView bound to List of a Class1 as in my previous question (By the way - the answer there was to use properties instead of fields) . I'm then adding a row with the following code:
l.Add(new Class1 { a = 5, b = 6 });
I checked and the Row is added to the List. But the DataGridView is not being updated. How is that fixed?
You have to re-Assign the Datasource, in case of any changes made in the bounded source, or that are in two way bounded:
grid.DataSource = null;
grid.DataSource = l;
The property AllowUserToAddRows of the DataGridView must be true.
The DataSource for the DataGridView must be a BindingSource. Its property AllowNew must be true.
You can create a BindingSource (here named personBindingSource) for the DGV in the Designer by editing its property DataSource... The DataSource of the BindingSource might be a List<Person>.
So this works fine...
// personBindingSource was already created in the Designer ...
personBindingSource.DataSource = null;
personBindingSource.DataSource = _lstPerson;
dgvPerson.DataSource = personBindingSource;
dgvPerson.Refresh();
The new line will be shown :-)
This does not work...
dgvPerson.DataSource = _lstPerson;
dgvPerson.Refresh();
the DGV still contains all elements but in this case the new line will not be shown :-(
Maybe this helps ...
An answer to another question of mine solved this one as well. Use a BindingSource as an intermediate, and use:
bindingSource.Add(new Class1 { a = 5, b = 6 });
you should set it following way. after you add new item in the list, you must set Datasource null, and reassign it to dataGridview.
List<Person> lst = new List<Person>();
private void button5_Click(object sender, EventArgs e)
{
lst.Add(new Person("X"));
lst.Add(new Person("y"));
dataGridView2.DataSource = lst;
lst.Add(new Person("Z"));
dataGridView2.DataSource = null;
dataGridView2.DataSource = lst;
}
public class Person
{
public Person(string fname)
{
this.firstname = fname;
}
public string firstname { get; set; }
}
you can use BindingSource, here I have example with Datatable, when any thing get changed in datasource it will reflected at the same time without any refresh function. If want to add new row, just need to update datatable.
private BindingSource bindingSource = new BindingSource();
bindingSource.DataSource = dt;
//datagridview column binding
ID.DataPropertyName = "ID";
Name.DataPropertyName = "Name";
grdCharges.DataSource = bindingSource;
currently I have a combobox with three hard coded items.
Each item carries 2 values. I'm using a switch case statement to get the values for each item depending on which item is selected.
Switch(combobox.selectedindex)
{
case 0: // Item 1 in combobox
a = 100;
b = 0.1;
break;
case 1: // Item 2 in combobox
a = 300;
b = 0.5;
break;
//and so on....
}
I'm trying to add a feature to allow the user to add more items into the combobox with inputted a and b values. How would i be able to dynamically add case statements and define the values under each case condition? I've had a look at using a datatable instead but I don't know how to get multiple valuemembers out of the datatable when one item is selected.
Also, I would like to save the user added items and it's corresponding values to a .dat file. So when the program is re-opened it will be able to load the list of items added by the user from the file. I considered using streamwriter and readline for this but I'm unsure how it would be done.
You can use Binding on a combobox using the DataSource. The ComboBox can also be bound to other things than Primitive values (string/int/hardcoded values). So you could make a small class that represents the values you are setting in your switch statement, and then use the DisplayMember to say which property should be visible in the combobox.
An example of such a basic class could be
public class DataStructure
{
public double A { get; set; }
public int B { get; set; }
public string Title { get; set; }
}
Since you are talking about users adding values to the combobox dynamically, you could use a BindingList that contains the separate classes, this BindingList could be a protected field inside your class, to which you add the new DataStructure when the user adds one, and then automatically updates the combobox with the new value you added.
The setup of the ComboBox, can be done in either Form_Load, or in the Form Constructor (after the InitializeComponent() call), like such:
// your form
public partial class Form1 : Form
{
// the property contains all the items that will be shown in the combobox
protected IList<DataStructure> dataItems = new BindingList<DataStructure>();
// a way to keep the selected reference that you do not always have to ask the combobox, gets updated on selection changed events
protected DataStructure selectedDataStructure = null;
public Form1()
{
InitializeComponent();
// create your default values here
dataItems.Add(new DataStructure { A = 0.5, B = 100, Title = "Some value" });
dataItems.Add(new DataStructure { A = 0.75, B = 100, Title = "More value" });
dataItems.Add(new DataStructure { A = 0.95, B = 100, Title = "Even more value" });
// assign the dataitems to the combobox datasource
comboBox1.DataSource = dataItems;
// Say what the combobox should show in the dropdown
comboBox1.DisplayMember = "Title";
// set it to list only, no typing
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
// register to the event that triggers each time the selection changes
comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
}
// a method to add items to the dataItems (and automatically to the ComboBox thanks to the BindingContext)
private void Add(double a, int b, string title)
{
dataItems.Add(new DataStructure { A = a, B = b, Title = title });
}
// when the value changes, update the selectedDataStructure field
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox combo = sender as ComboBox;
if (combo == null)
{
return;
}
selectedDataStructure = combo.SelectedItem as DataStructure;
if (selectedDataStructure == null)
{
MessageBox.Show("You didn't select anything at the moment");
}
else
{
MessageBox.Show(string.Format("You currently selected {0} with A = {1:n2}, B = {2}", selectedDataStructure.Title, selectedDataStructure.A, selectedDataStructure.B));
}
}
// to add items on button click
private void AddComboBoxItemButton_Click(object sender, EventArgs e)
{
string title = textBox1.Text;
if (string.IsNullOrWhiteSpace(title))
{
MessageBox.Show("A title is required!");
return;
}
Random random = new Random();
double a = random.NextDouble();
int b = random.Next();
Add(a, b, title);
textBox1.Text = string.Empty;
}
}
Like this, you have the selected item always at hand, you can request the values from the properties of the selected, and you don't have to worry about syncing the ComboBox with the items currently visible
From the documentation:
Although the ComboBox is typically used to display text items, you can add any object to the ComboBox. Typically, the representation of an object in the ComboBox is the string returned by that object's ToString method. If you want to have a member of the object displayed instead, choose the member that will be displayed by setting the DisplayMember property to the name of the appropriate member. You can also choose a member of the object that will represent the value returned by the object by setting the ValueMember property. For more information, see ListControl.
So you can just add objects that hold all the information, directly to the Items collection of the ComboBox. Later, retrieve the SelectedItem property and cast it back to the correct type.
I am trying to get the Row's particular column from selected item in wpf from DataGrid.
Name of DataGrid is Datagrid_Newsale.
I am getting alert of whole row when it is selected, So i tried mapping its column.
Say if row is-
{ ID = 3, CustomerName = xyz, SaleDate = 05.08.2013 00:00:00, TotalAmount = 10 }
Then it's column CustomerName=xyz is to be shown in textbox.
Getting row-
var copyitem = Datagrid_NewSale.SelectedItem;
if (copyitem == null)
{
MessageBox.Show("Please select values from list");
}
if (copyitem != null)
{
MessageBox.Show(copyitem.ToString());
}
For getting customerName into text box i tried creating a new instance of model-
public class CustomerDetailes
{
public string CustomerName { get; set; }
}
And values from database from Customer Table-
public void viewcustomername()
{
List<CustomerDetailes> ilist = null;
ilist = (from order in db.Customer
select new CustomerDetailes
{
CustomerName= order.CustomerName
}).ToList();
txtCustumer.Text = ilist.ToString();
}
So giving it one more try-
CustomerDetailes copyitem = (CustomerDetailes)Datagrid_NewSale.SelectedItem;
if (copyitem == null)
{
MessageBox.Show("Please select values from list");
}
if (copyitem != null)
{
MessageBox.Show(copyitem.ToString());
}
txtCustomer.text=copyitem.CustomerName; //CustomerName into a textbox
But it is referencing null in copyitem.
How can I get particular column from the whole row.
You will have to bind the ItemsSource of DataGrid to CustomerDetails collection in order to get CustomDetails in SelectedItem.
Create property in your viewmodel (if using MVVM) or in code behind like
List<CustomerDetails> customerDetails = new List<CustomerDetails>();
List<CustomerDetails> MyCollection
{
get
{
return myList;
}
set
{
myList = value;
PropertyChanged(this, new PropertyChangedEventArgs("MyCollection"));
}
}
and in xaml just do.
<DataGrid ItemsSource="{Binding MyCollection}"/>
OR if you are directly filling the Items in the datagrid add instances of CustomerDetails like
dataGrid.Items.Add(new CustomerDetails(){Name = "abc"}, xyz propertis)
Thanks
If you can access the grid from your selection event then following should give your the column
((DataGrid)sender).CurrentCell.Column.Header
and use some mapping for the column name to the property of the object your want to show
I came up with this easy solution.
Mapped datatype of copyitem that was Anonymous in my case. In this case using Dynamic datatype solved my problem.
Due to my data was coming dynamically and then i was trying to map out particular column, so it was not really possible to do it statically because there is not data then.
Using Dynamic Datatype-
dynamic copyitem = dataGrid1.SelectedItem;
Accessing property-
int localId = copyitem.ID;
furthermore for customerName,TotalAmount i did the same.
Linq Query changes-
var query= (from order in db.Customer
where order.ID=localId
select order).ToList();
DataGrid_OpenSale.ItemsSource=query // returning data to another datagrid.
in VB ⠀⠀⠀
Private Sub SCUSTDataGrid_GotFocus(sender As Object, e As RoutedEventArgs) Handles SCUSTDataGrid.GotFocus
Dim og As DataGridCell = e.OriginalSource
Dim ccontent As TextBlock = og.Content
Dim dg As DataGrid
dg = e.Source
Dim selcol As String = dg.CurrentCell.Column.Header.ToString
MessageBox.Show(selcol.ToString + ccontent.Text + " got focus event")
End Sub
I have a datagridview which I fill it as below :
var q= repository.GetStudents();//
dataGridView1.DataSource = null;
dataGridView1.Columns.Clear();
dataGridView1.DataSource = q;
dataGridView1.Columns.RemoveAt(1);
//Remove IsActive
//Cause I want to have my own implementation
dataGridView1.Columns[0].DataPropertyName = "StudentID";
dataGridView1.Columns[0].HeaderText = "Studunet ID";
dataGridView1.Columns[1].DataPropertyName = "IsActive";
dataGridView1.Columns[1].HeaderText = "Status";
The "IsActive" property is of boolean Type. When the "IsActive" cell is being displayed, it show true/false. I want to replace it with my own custom value.
I read this and this posts but I could not resolve my problem.
You can use the CellFormatting event of the DataGridView, e.g.:
void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
var grid = (DataGridView)sender;
if (grid.Columns[e.ColumnIndex].Name == "IsActive")
{
e.Value = (bool)e.Value ? "MY_TEXT_FOR_TRUE" : "MY_TEXT_FOR_FALSE";
e.FormattingApplied = true;
}
}
EDIT (as per comment):
It's very similar to what you're doing now, just remove the bound column and add a new column of the desired type and set the DataPropertyName properly e.g. :
this.dataGridView1.Columns.Remove("COL_TO_CUSTOMIZE");
var btnCol = new DataGridViewDisableButtonColumn();
btnCol.Name = "COL_TO_CUSTOMIZE";
btnCol.DataPropertyName = "COL_TO_CUSTOMIZE";
var col = this.dataGridView1.Columns.Add(btnCol);
Note that this append the column at the end, but you can decide the position of the column by using dataGridView.Columns.Insert method instead of Add.
One of the funky things about a DataGridViewComboBoxColumn is that you can give it one data source that has a column of values to lookup and a column of values to show, and you can bind it to another column of values and then it will perform the lookup for you
So, suppose your collection q of Students (or whatever they are) has an IsActive true/false and you want this to show as "All the time", or "Not a chance".. Let's hash together a combobox that does this:
var cb = new DataGridViewComboBoxColumn();
cb.DisplayMember = "DisplayMe"; //the related text to show in the combo
cb.ValueMember = "ValueToLookup"; //the name in the combo's lookup list
cb.DataPropertyName = "IsActive"; //the name of your property on Student, to look up
cb.DataSource = "All the time,Not a Chance"
.Split(',')
.Select(s => new { DisplayMe = s, ValueToLookup = (s[0] == 'A') } )
.ToList();
It doesn't really matter how we generat the combo's datasource; here I've made a string into a List<anonymous_string+bool> by splitting, then selecting a new anonymous type with the two property names I need; you can use anything that has some named properties - a List of KeyValuePair, Tuple, whatever..
The critical thing is that the combo can read the q.IsActive bool you cited in DataPropertyName, look that bool up in its list in the property named in the ValueMember, then display the property named in the DisplayMember. It works for editing too, so the user can choose a new item from the combo and the translation works back the other way - "what does the user choose? what is the value of its property named in ValueMember, put that value into the student IsActive property named in DataPropertyName".. And it doesnt stop at bools either; the value member can be anything - an int, date etc