LookUpEdit does not work - c#

I have XtraTabControl with two pages, both of them has one LookUpEdit,
when page load which on the secondpage does not work,
void Frm1_Load(object sender, EventArgs e)
{
lookUpEditA.Properties.DataSource = datasource. . . . .
lookUpEditA.Properties.ValueMember = "ID";
lookUpEditA.Properties.DisplayMember = "xxxx";
lookUpEditA.Properties.PopulateColumns();
lookUpEditA.Properties.Columns["ID"].Visible = false;
lookUpEditB.Properties.DataSource = datasource. . . . .
lookUpEditB.Properties.ValueMember = "ID";
lookUpEditB.Properties.DisplayMember = "xxxx";
lookUpEditB.Properties.PopulateColumns();
lookUpEditB.Properties.Columns["ID"].Visible = false;
}

I can see the issue only with setting visibility of 'ID' column on second LookUpEdit.
The reason of this issue is that the LookUpEdit can't operate with datasource representation (perform populating columns, operating with column's visibility and etc.) until it's handle been created. The second LookUpEdit will create it's handle only when the second tab page has been shown.
To avoid the issue you can use the following approach:
if(!lookUpEditB.IsHandleCreated)
lookUpEditB.HandleCreated += lookUpEditB_HandleCreated;
else InitLookUpEditDataSource();
//...
void lookUpEditB_HandleCreated(object sender, EventArgs e) {
lookUpEditB.HandleCreated -= lookUpEditB_HandleCreated;
InitLookUpEditDataSource();
}
void InitLookUpEditDataSource() {
lookUpEditB.Properties.DataSource = this.categoriesBindingSource;
lookUpEditB.Properties.DisplayMember = "CategoryName";
lookUpEditB.Properties.ValueMember = "CategoryID";
lookUpEditB.Properties.PopulateColumns();
lookUpEditB.Properties.Columns["CategoryID"].Visible = false;
}

As #DmitryG said, you can not use lookUpEditB.Properties.PopulateColumns() statement until control's UI handlers are not created.
As per my understanding these are created only when the second tab page shown. Except creating conditional statement to create handlers etc, you can use the XtraTabControl.SelectedPageChanged Event where you can bind the data source of the lookUpEditB by checking condition that XtraTabControl.SelectedTabPage Property is set with Page2 which contain the lookUpEditB.
Check the tested Code Snippet below:
public partial class TabControlTest : Form
{
List<Category> dataSource = new List<Category>();
public TabControlTest()
{
InitializeComponent();
for (int i = 0; i < 10; i++)
{
dataSource.Add(new Category { ID = i + 1, Name = "Category" + (i + 1) });
}
}
private void TabControlTest_Load(object sender, EventArgs e)
{
lookUpEditA.Properties.DataSource = dataSource;
lookUpEditA.Properties.ValueMember = "ID";
lookUpEditA.Properties.DisplayMember = "Name";
lookUpEditA.Properties.PopulateColumns();
lookUpEditA.Properties.Columns["ID"].Visible = false;
}
private void xtraTabControl1_SelectedPageChanged(object sender, DevExpress.XtraTab.TabPageChangedEventArgs e)
{
if (xtraTabControl1.SelectedTabPage == xtraTabPage2)
{
lookUpEditB.Properties.DataSource = dataSource;
lookUpEditB.Properties.ValueMember = "ID";
lookUpEditB.Properties.DisplayMember = "Name";
lookUpEditB.Properties.PopulateColumns();
lookUpEditB.Properties.Columns["ID"].Visible = false;
}
}
}
Hope this help.

Related

Change visible state of DataGridView only given its name

I have a form application where multiple DataGridView objects are to be displayed (but not at once). They should be created on top of each other and it should then be possible to toggle the displayed DataGridView using a ComboBox.
I have a function which should create new DataGridView every time its called and then adds the name to the ComboBox:
private void readCSV(string DBname)
{
DataGridView tagDBname = new DataGridView();
tagDBname.Location = new System.Drawing.Point(24, 260);
tagDBname.Name = DBname;
tagDBname.Size = new System.Drawing.Size(551, 217);
tagDBname.TabIndex = 6;
tagDBname.Columns.Add("Column1", "Col1");
tagDBname.Columns.Add("Column2", "Col2");
tagDBname.Visible = false;
comboBoxTag.Items.Add(DBname);
}
Then I would like to change the visibility state of a DataGridView given the selected name from the ComboBox. This should be done in the function called when the index changes:
private void comboBoxTag_SelectedIndexChanged(object sender, EventArgs e)
{
// Get the name of the DataGridView which should be visible:
string selectedTagDB = comboBoxTagDatabases.SelectedItem.ToString();
DataGridView tagDatabase = ? // Here the DataGridView should be selected given the name "selectedTagDB"
tagDatabase.Visible = true;
}
In the above, I do not know how to assign the DataGridView only given its name. Any help would be appreciated - even if it means that the selected approach is inappropriate of what I am trying to achieve. If the question is answered elsewhere, feel free to guide me in the right direction :)
I would store the gridviews in a dictionary by using the DB name as key;
private readonly Dictionary<string, DataGridView> _tagDBs =
new Dictionary<string, DataGridView>();
private void readCSV(string DBname)
{
DataGridView tagDBname = new DataGridView();
// Add the gridview to the dictionary.
_tagDBs.Add(DBname, tagDBname);
tagDBname.Name = DBname;
tagDBname.Location = new System.Drawing.Point(24, 260);
tagDBname.Size = new System.Drawing.Size(551, 217);
tagDBname.TabIndex = 6;
tagDBname.Columns.Add("Column1", "Col1");
tagDBname.Columns.Add("Column2", "Col2");
tagDBname.Visible = false;
this.Controls.Add(tagDBname); // Add the gridview to the form ot to a control.
comboBoxTag.Items.Add(DBname);
}
private void comboBoxTag_SelectedIndexChanged(object sender, EventArgs e)
{
// Get the name of the DataGridView which should be visible:
string selectedTagDB = comboBoxTagDatabases.SelectedItem.ToString();
foreach (DataGridView dgv in _tagDBs.Values) {
dgv.Visible = dgv.Name == selectedTagDB; // Hide all gridviews except the selected one.
}
}
If you need to do something with the selected gridview, you can get it with:
if (_tagDBs.TryGetValue(selectedTagDB, out DataGridView tagDatabase)) {
// do something with tagDatabase.
}
Note: you must add the gridview to the form or to a container control on the form. E.g.
this.Controls.Add(tagDBname);
You can loop through all DataGridViews of the form to display the expected one using its name, while hidding the others ones.
This solution isn't pretty but works
private void ShowOneDataGridViewAndHideOthers(string name)
{
foreach (var DGV in this.Controls.OfType<DataGridView>())
{
DGV.Visible = DGV.Name == name;
}
}
And call it this way :
private void comboBoxTag_SelectedIndexChanged(object sender, EventArgs e)
{
// Get the name of the DataGridView which should be visible:
string selectedTagDB = comboBoxTagDatabases.SelectedItem.ToString();
ShowOneDataGridViewAndHideOthers(selectedTagDB);
}
The method can be made a bit more generic this way :
private void ShowOneControlAndHideOthers<T>(string name, Control controls) where T : Control
{
foreach (var control in controls.Controls.OfType<T>())
{
control.Visible = control.Name == name;
}
}
private void comboBoxTag_SelectedIndexChanged(object sender, EventArgs e)
{
// Get the name of the DataGridView which should be visible:
string selectedTagDB = comboBoxTagDatabases.SelectedItem.ToString();
ShowOneControlAndHideOthers<DataGridView>(selectedTagDB, this);
}

DataGridView not loading data programmatically

I am working on a Windows application where I get an input from a TextBox and add it to the DataGridView when user clicks on a Button (Add).
My problem is that when I add the text for the first time, it works fine and its added to the grid.
When I add new text, it's not added to the DataGridView. Once the Form is closed and reopened with the same object then I am able to see it.
Code:
private void btnAddInput_Click(object sender, EventArgs e)
{
if (Data == null)
Data = new List<Inputs>();
if (!string.IsNullOrWhiteSpace(txtInput.Text))
{
Data.Insert(Data.Count, new Inputs()
{
Name = txtInput.Text,
Value = string.Empty
});
}
else
{
MessageBox.Show("Please enter parameter value", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
txtInput.Text = "";
gridViewInputs.DataSource = Data;
}
I am not sure what is causing the record not to be added to grid on second add button click.
You could set the DataGridView.DataSource to null before setting a new one.
This would cause the DataGridView to refresh its content with the new data in the source List<Inputs>:
the underlying DataGridViewDataConnection is reset only when the DataSource reference is different from the current or is set to null.
Note that when you reset the DataSource, the RowsRemoved event is raised multiple times (once for each row removed).
I suggest to change the List to a BindingList, because any change to the List will be reflected automatically and because it will allow to remove rows from the DataGridView if/when required: using a List<T> as DataSource will not allow to remove a row.
BindingList<Inputs> InputData = new BindingList<Inputs>();
You can always set the AllowUserToDeleteRows and AllowUserToAddRows properties to false if you don't want your Users to tamper with the grid content.
For example:
public class Inputs
{
public string Name { get; set; }
public string Value { get; set; }
}
internal BindingList<Inputs> InputData = new BindingList<Inputs>();
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = InputData;
}
private void btnAddInput_Click(object sender, EventArgs e)
{
string textValue = txtInput.Text.Trim();
if (!string.IsNullOrEmpty(textValue))
{
InputData.Add(new Inputs() {
Name = textValue,
Value = "[Whatever this is]"
});
txtInput.Text = "";
}
else
{
MessageBox.Show("Not a valid value");
}
}
If you want to keep using a List<T>, add the code required to reset the DataGridView.DataSource:
private void btnAddInput_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(textValue))
{
//(...)
dataGridView1.DataSource = null;
dataGridView1.DataSource = InputData;
txtInput.Text = "";
}
//(...)

How to update datagridview based off of combo box selection?

I am attempting to write code that will display data in a datagridview based off of the size of car selected in a combo box. When this code initially runs, it defaults to economy sized, and displays the correct information in the datagridview. However, when a different size is selected in the combo box, the text boxes update correctly while the datagridview remains the same. What can I do to make it update every time the combo box is changed? I thought the code in "private void cboSize_selectionChangeCommitted()" would accomplish this, but there was no change in the output.
namespace carForm
{
public partial class Form1 : Form
{
_Cars_1_DataSet cDataSet;
BindingSource sizeBindingSource;
BindingSource vehicleBindingSource;
CarsDataClass clsCarsData;
Boolean gridInitialized;
public Form1()
{
InitializeComponent();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the '_Cars_1_DataSet.Reservations' table. You can move, or remove it, as needed.
this.reservationsTableAdapter.Fill(this._Cars_1_DataSet.Reservations);
// TODO: This line of code loads data into the '_Cars_1_DataSet.Vehicle' table. You can move, or remove it, as needed.
this.vehicleTableAdapter.Fill(this._Cars_1_DataSet.Vehicle);
// TODO: This line of code loads data into the '_Cars_1_DataSet.CarSize' table. You can move, or remove it, as needed.
this.carSizeTableAdapter.Fill(this._Cars_1_DataSet.CarSize);
clsCarsData = new CarsDataClass();
cDataSet = clsCarsData.GetDataSet();
//Binding source sizes
sizeBindingSource = new BindingSource();
sizeBindingSource.DataSource = cDataSet;
sizeBindingSource.DataMember = "CarSize";
//Binding source vehicles
vehicleBindingSource = new BindingSource();
vehicleBindingSource.DataSource = cDataSet;
vehicleBindingSource.DataMember = "Vehicle";
//Combo box
cboSize.DataSource = sizeBindingSource;
cboSize.DisplayMember = "Size";
cboSize.ValueMember = "SizeCode";
//bind other controls
txtDaily.DataBindings.Add("text", sizeBindingSource, "DailyRate");
txtMileage.DataBindings.Add("text", sizeBindingSource, "MileageRate");
//execute combo box
cboSize_SelectionChangeCommitted(cboSize, e);
}
private void cboSize_SelectionChangeCommitted(object sender, EventArgs e)
{
string carSelected;
carSelected = Convert.ToString(cboSize.SelectedValue);
if (!gridInitialized)
{
dgvVehicles.DataSource = vehicleBindingSource;
gridInitialized = true;
ChangeGridColumns();
}
vehicleBindingSource.Filter = "CarSize = '" + carSelected + "'";
}
private void ChangeGridColumns()
{
//Change column headers
//dgvVehicles.Columns["Inv_ID"].Visible = false;
}
}
}
Try using SelectedIndexChanged event from the events menu after clicking on the combobox in the design view.
This should populate in your code:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Console.WriteLine("test!");
}
In there you can put this logic from your code:
string carSelected;
carSelected = Convert.ToString(cboSize.SelectedValue);
if (!gridInitialized)
{
dgvVehicles.DataSource = vehicleBindingSource;
gridInitialized = true;
ChangeGridColumns();
}
vehicleBindingSource.Filter = "CarSize = '" + carSelected + "'";
Use SelectedIndexChanged instead of SelectionChangeCommitted.

How to get data from SQL database to store in to a combo box - C#

How can i get the value of outlet ID it on a comboBox?
here is my code to getting the values from Database and store it on a combobox.
public partial class Addstock : Form
{
String connectionString = ConfigurationManager.ConnectionStrings["TCConnectionString"].ConnectionString;
List<BOStockTransfer> StockList = new List<BOStockTransfer>();
int updateIndex = -1;
public Addstock()
{
InitializeComponent();
}
private void Addstock_Load(object sender, EventArgs e)
{
loadstock();
GetOutlets();
Getproduct();
GetGetWH();
cmdoutletID.Visible = false;
lbloutid.Visible = false;
cmdwh.Visible = false;
lblwh.Visible = false;
}
private void GetOutlets()
{
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
if (ds_OutletList.Tables[0].Rows.Count != 0)
{
cmdoutletID.DataSource = ds_OutletList.Tables[0];
cmdoutletID.DisplayMember = "outletId";
}
}
Thank you for your help!
you are setting :
cmdoutletID.Visible = false;
what makes the combobox invisible
you have to set it as follows :
cmdoutletID.Visible = true;
After you added the images , the column name is outletID and Not outletId
so change your code as follows :
private void GetOutlets()
{
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
if (ds_OutletList.Tables[0].Rows.Count != 0)
{
cmdoutletID.DataSource = ds_OutletList.Tables[0];
cmdoutletID.DisplayMember = "outletID";
cmdoutletID.ValueMember = "outletID";
cmdoutletID.Enabled = true;
}
}
The combo box has two properties which determine where it loads data from:
DisplayMember
ValueMember
The "ValueMember" property defines which named field populates the ListItem's "ValueProperty". That way, when you do combobox.SelectedItem.Value, you will get the value stored in the named field you specified for "ValueProperty".
Assuming that you are certain that your query is returning rows, perhaps try adding the items "manually" rather than relying on automatic databinding.
private void GetOutlets()
{
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
cmdoutletID.DisplayMember = "outletId";
cmdoutletID.ValueMember = "pkID";
cmdoutletID.BeginUpdate();
try
{
cmdoutletID.Items.Clear();
foreach (var row in ds_OutletList.Tables[0].Rows)
cmdoutletID.Items(new { outletid = row["outletid"], pkID = row["primaryKeyIDFieldName"] });
}
finally { cmdoutletID.EndUpdate(); }
}
Try this:
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
if (ds_OutletList.Tables[0].Rows.Count != 0)
{
cmdoutletID.DataSource = ds_OutletList.Tables[0];
cmdoutletID.DisplayMember = "outletname";
cmdoutletID.ValueMember = "outletId";
}
To capture selected value, for example on button click:
protected button1_Click(object o, EventArgs e)
{
var selectedId = cmboutletID.SelectedValue;
MessageBox.Show(selectedId);
}

How to bind class fields to ItemTemplate

I have a Windows Store App project.
I created a Items Page. It's all default and i want to bind my custom class to it's GridView so that the elements can be properly displayed.
The GridView's ItemTemplate is set to Standard250x250ItemTemplate. I would like to use that template and tell it how to display my custom elements. How can i do that? Do i have to create my own ItemTemplate? I would like to use the existing one.
Btw I'm setting itemGridView.ItemsSource to my collection. Is that the correct way of telling the GridView what to display?
you need to create your item template
here is an example i did it using Obout Ajax LIB
Grid SegmentsGrid = new Grid();
GridRuntimeTemplate AirlinesTemplate = new GridRuntimeTemplate();
AirlinesTemplate.ID = "AirlinesTemplate1";
AirlinesTemplate.ControlID = "AirlinesComboBox1";
AirlinesTemplate.Template = new Obout.Grid.RuntimeTemplate();
AirlinesTemplate.Template.CreateTemplate += new Obout.Grid.GridRuntimeTemplateEventHandler(CreateAirlinesTemplate);
GridRuntimeTemplate ClassesTemplate = new GridRuntimeTemplate();
ClassesTemplate.ID = "ClassesTemplate1";
ClassesTemplate.ControlID = "ClassesComboBox1";
ClassesTemplate.Template = new Obout.Grid.RuntimeTemplate();
ClassesTemplate.Template.CreateTemplate +=new Obout.Grid.GridRuntimeTemplateEventHandler(CreateClassesTemplate);
SegmentsGrid.Templates.Add(ClassesTemplate);
SegmentsGrid.Templates.Add(AirlinesTemplate);
public void CreateAirlinesTemplate(Object sender, Obout.Grid.GridRuntimeTemplateEventArgs e)
{
PlaceHolder ph1 = new PlaceHolder();
e.Container.Controls.Add(ph1);
AirlinesComboBox.ID = "AirlinesComboBox1";
AirlinesComboBox.Width = Unit.Percentage(100);
AirlinesComboBox.Height = Unit.Pixel(200);
AirlinesComboBox.DataTextField = "Airline_Long_Name";
AirlinesComboBox.DataValueField = "Airline_Long_Name";
AirlinesComboBox.EmptyText = "Select Airline ...";
AirlinesComboBox.EnableLoadOnDemand = true;
AirlinesComboBox.LoadingItems += AirlinesComboBox1_LoadingItems;
ph1.Controls.Add(AirlinesComboBox);
}
protected void AirlinesComboBox1_LoadingItems(object sender, ComboBoxLoadingItemsEventArgs e)
{
// Getting the countries
DataTable data = GetAirlines(e.Text);
// Looping through the items and adding them to the "Items" collection of the ComboBox
for (int i = 0; i < data.Rows.Count; i++)
{
(sender as ComboBox).Items.Add(new ComboBoxItem(data.Rows[i]["Airline_Long_Name"].ToString(), data.Rows[i]["Airline_Long_Name"].ToString()));
}
e.ItemsLoadedCount = data.Rows.Count;
e.ItemsCount = data.Rows.Count;
}
protected void ClassesComboBox1_LoadingItems(object sender, ComboBoxLoadingItemsEventArgs e)
{
// Getting the countries
DataTable data = GetClasses(e.Text);
// Looping through the items and adding them to the "Items" collection of the ComboBox
for (int i = 0; i < data.Rows.Count; i++)
{
(sender as ComboBox).Items.Add(new ComboBoxItem(data.Rows[i]["Class_Name"].ToString(), data.Rows[i]["Class_Name"].ToString()));
}
e.ItemsLoadedCount = data.Rows.Count;
e.ItemsCount = data.Rows.Count;
}
public void CreateClassesTemplate(Object sender, Obout.Grid.GridRuntimeTemplateEventArgs e)
{
PlaceHolder ph1 = new PlaceHolder();
e.Container.Controls.Add(ph1);
ClassesComboBox.ID = "ClassesComboBox1";
ClassesComboBox.Width = Unit.Percentage(100);
ClassesComboBox.Height = Unit.Pixel(200);
ClassesComboBox.DataTextField = "Class_Name";
ClassesComboBox.DataValueField = "Class_Name";
ClassesComboBox.EmptyText = "Select Flight Class ...";
ClassesComboBox.EnableLoadOnDemand = true;
ClassesComboBox.LoadingItems += ClassesComboBox1_LoadingItems;
ph1.Controls.Add(ClassesComboBox);
}

Categories