Binding a textbox to a datagridviewtextboxcolumn? - c#

Is it possible, to bind (or similar) a standard textbox to display the contents (dynamically) of the selected cell within a datagridview textboxcolumn?
My goal is that when a cell within this column has it's value altered, the textbox.text is also changed, and when the user selects a cell then types something in this separate textbox the value is updating the datagridview textboxcolumns value on the fly.

Yes you may bind common dataSource to both TextBox and DataGridView.
public class Foo
{
public string Item { get; set; }
}
private void Form2_Load(object sender, EventArgs e)
{
List<Foo> list = new List<Foo>()
{
new Foo() { Item="1" },
new Foo() { Item="2" }
};
dataGridView1.DataSource = list;
textBox1.DataBindings.Add("Text", list, "Item");
}

Applying the idea from "adatapost" to a DataGridView in C#:
TextBox txt = this.txtBox1;
DataGridView dgv = this.datagridview1;
txt.DataBindings.Add("Text", dgv.DataSource, "FieldName");
dgv = null;
txt = null;
It might not be necessary to declare separate variables to hold your TextBox and DataGridView while you create the Binding. I just show these for clarity, in fact, this would be sufficient:
this.txtBox1.DataBindings.Add("Text", this.datagridview1.DataSource, "FieldName"
To clarify, "Text" means output the value back to the "Text" property of the TextBox, and "FieldName" should be replaced with whatever the column is in your DataGridView that you want to bind to.
Note - make sure that you have already set the DataSource / populated the DataGridView before you put the Binding code, if the DataSource is not set and therefore containing the field that you wish to bind to you will get an error.

Related

DataGridView Row Tag

I have a Datagridview, and a field from the database. I want save this field to row tag in gridview, but after saving to the tag with a Foreach loop, in another function I see it returns null value.
How do I save this field?
Thank you
private void UC_DKHoc_Load(object sender, EventArgs e)
{
var dsLop = LopDangKyServices.LayDanhSachLopDangKy();
var DatasourceGV = from lop in dsLop
select new
{
lop.MaLopDangKy,
lop.TenLopDangKy,
lop.CLB1.TenCLB,
lop.NamHoc,
lop.HocPhi,
lop.LichHoc
};
advancedDataGridView.DataSource = DatasourceGV.ToList(); // Display to gridview
int i = 0;
foreach (DataGridViewRow row in advancedDataGridView.Rows)
{
row.Tag = dsLop[i++].CLB; //save complete
}
advancedDataGridView.DisableFilter(STT);
}
In The function I see null values.
private void simpleButton1_Click(object sender, EventArgs e)
{
MessageBox.Show(advancedDataGridView.Rows[1].Tag.ToString()); //Null value
}
You can use either of the following options:
Include all the properties which you need in the list (including CLB). Then after assigning the list as DataSource of the DataGridView, hide the corresponding column:
advancedDataGridView.DataSource = list;
advancedDataGridView.Columns["CLB"].Visible = false;
Create a model class containing all the properties which you need, including CLB. Then just decorate CLB with [Browsable(false)] attribute. (You need to select the result by creating instance of the model class, rather than anonymous type.)
[Browsable(false)]
public int CLB { get; set;}
Set AutoGenerateColumns of DataGridView to false and add desired columns to DataGridView. Make sure you set Name, DataPropertyName and HeaderText. Then set DataSource of DataGridView to the list which contains all properties, including CLB:
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn() {
Name = "MaLopDangKy",
DataPropertyName = "MaLopDangKy",
HeaderText = "MaLopDangKy" });
//Add rest of columns ...
dataGridView1.AutoGenerateColumns = false;
dataGridView1.DataSource = list;
You can decide to add CLB as an invisible column of DataGridView. Even if you didn't add it as a column, you can access to the DataBoundItem property of the DataGridViewRow which points to the list member instance which is displaying the the row. Cast it to the list member type and use its CLB property.

how to display custom text in data bound GridViewComboBoxColumn

I am working on RadGridView of telerik. I have a "GridViewComboBoxColumn" with a list of strings as data source.
Now the problem is that when I populate the grid view with data, it is possible that the value in data is not available in the strings data source for that column which results in blank value.
I tried setting DropDownStyle to RadDropDownStyle.DropDown but that doesn't change anything. And I just need to display the data even if that is not present in the drop down list.
Here is some code to help you understand it better.
Dim lstValues As New List(Of String)
lstValues.Add("Approved")
lstValues.Add("Declined")
lstValues.Add("Pending")
Dim col5 As GridViewComboBoxColumn = RadGridView1.Columns("column2")
col5.DataSource = lstValues
col5.DropDownStyle = Telerik.WinControls.RadDropDownStyle.DropDown
Now the row being added would be following.
RadGridView1.Rows.Add("Application Name", "Processing")
As you can see that column2 has no item named "Processing" so it is not displayed and showing as blank.
Thanks in advance for the help.
Regards
You can use the formatting events and set the cell text to whatever you need, however, note that the cell value will not be changed by this, but this is what you need as far as I can understand.
void radGridView1_CellFormatting(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e)
{
if (e.Column.Name == "column2" && e.Row.Cells["someColumn"].Value == something)
{
e.CellElement.Text = "some text";
}
else
{
e.CellElement.ResetValue(LightVisualElement.TextProperty, ValueResetFlags.Local);
}
}

Add items to combobox with multiple values C#

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.

Setting DataSource to DataGridViewComboBoxColumn

I'm trying to set DataSource to DataGridViewComboBoxColumn of my DataGridView. First I'm trying to bind a data source to my DataGridView, where bindingList is a List of my custom class Plugin with properties Name (string), Id (string) and Dependencies (List):
var bindingList = PluginsHandler.GetPlugins();
var source = new BindingSource(bindingList, null);
pluginsDataGridView.AutoGenerateColumns = false;
pluginsDataGridView.DataSource = source;
pluginsDataGridView.Columns["pluginName"].DataPropertyName = "Name";
pluginsDataGridView.Columns["pluginID"].DataPropertyName = "Id";
So I can set my first two columns, but now I want to bind data to a third column of type DataGridViewComboBoxColumn. I try to do it on DataBindingComplete event:
private void pluginsDataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
for (int i = 0; i < pluginsDataGridView.Rows.Count; i++)
{
var comboCell = (DataGridViewComboBoxCell) pluginsDataGridView.Rows[i].Cells["pluginDependencies"];
var entry = pluginsDataGridView.Rows[i].DataBoundItem as IPlugin;
comboCell.DataSource = entry.Dependencies;
}
}
Sadly comboBox is empty. Funny thing happens when I incorrectly put these lines after the first block of code I posted:
var dependenciesColumn = (DataGridViewComboBoxColumn) pluginsDataGridView.Columns["pluginDependencies"];
dependenciesColumn.DataPropertyName = "Dependencies";
Then binding seem to start to work, as I can see that there are some entries in comboboxes, but when I try to hover mouse on combobox, I am getting an error that says DataGridViewComboBoxCell value is not valid).
How can I make it work?
Instead of assigning each ComboCell a data Source, set the DataSource of the column. I assume the Dependencies property of PlugIn class is a List<string>.
pluginsDataGridView.Columns["pluginDependencies"].DataSource = //list of dependencies
You have to set the DataPropertyName of the Dependencies ComboBoxColumn to get the initial values. If you don't set it you won't see any value in the column when the application is loaded.
pluginsDataGridView.Columns["pluginDependencies"].DataPropertyName = "Dependencies"
Edit:
You have a list of dependencies for a plug-in. i.e, more than one value. Usually, to select one value from list of values, you associate list with ComboBoxColumn. Achieving your requirement of multiple values from a list using standard ComboBoxColumn is difficult. Write a custom CheckedComboBoxColumn where you can display and select multiple values.

Bindingsource datagridview click fill data in textbox

I have a datagridview which is bind from a bindingsource I really try to find out how onclick row on datagridview the row data fill in the TextBox. Because I want to show some data on combobox according selection on datagridview. My code for bind the datagridview is below
private void FillGrid()
{
if (_fisComp == null)
_fisComp = new FiscalComponent();
List<FiscalPeriod> _fisPeriod = _fisComp.GetAllByFiscalPeriod(Convert.ToString(fiscalYearComboBox.SelectedValue));
fiscalPeriodBindingSource.DataSource = _fisPeriod;
fiscalPeriodDataGridView.Refresh();
}
I am binding my datagridview by list<> type . The problem is that I am getting data from my stored procedure Y~N` and i want to display in combobox in Yes or No
This code is where I am binding my combobox
public void FillDropdown()
{
var itemsleaverun = new BindingList<KeyValuePair<string, string>>();
itemsleaverun.Add(new KeyValuePair<string, string>("Y", "Yes"));
itemsleaverun.Add(new KeyValuePair<string, string>("N", "No"));
leaveRunTypeComboBox.DataSource = itemsleaverun;
leaveRunTypeComboBox.ValueMember = "Key";
leaveRunTypeComboBox.DisplayMember = "Value";
leaveRunTypeComboBox.SelectedIndex = 0;
}
To bind one of the properties of FiscalPeriod to your combobox. I suppose you want to bind the Property X which can have values "Yes" or "No". You can bind it to your combobox like this:
yourComboBox.DataBindings.Add("Text", fiscalPeriodBindingSource, "X");
The Property X should be able to have values which are contained in the Items list of your comboBox. Because your combobox has a DataSource, they should be contained in the values list for the DataSource DisplayMember.

Categories

Resources