Combobox does not revert to null when value is cleared - c#

Due to a flaw in .NET (Microsoft says its intended but I see it as a serious flaw)
If a user empties a combo box (i.e. wants to blank out the value) the selected value does not revert to null instead it keeps the last valid selected value, so when you save with a blank combobox it goes back to the original value.One workaround is to first choose a different option from the drop down, then blank it out and it will work properly. However, that's not something users of an application would prefer.
So is there a way that I can fix this. Or is it possible that I can add an option for "NONE" which will then change the value in the database to NULL. Note: Combobox has data-binding and I was not able to add the option none for Names.
Contents of the Form.Desginer.cs:
private void InitializeComponent()
{
......
this.cmbSecCSR = new System.Windows.Forms.ComboBox();
this.csrBindingSource2 = new System.Windows.Forms.BindingSource(this.components);
.....
//
// pnlCSRs
//
this.pnlCSRs.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pnlCSRs.Controls.Add(this.cmbSecCSR);
......
//
// cmbSecCSR
//
this.cmbSecCSR.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
this.cmbSecCSR.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.cmbSecCSR.DataSource = this.csrBindingSource2;
this.cmbSecCSR.DisplayMember = "Name";
this.cmbSecCSR.FormattingEnabled = true;
this.cmbSecCSR.Location = new System.Drawing.Point(112, 26);
this.cmbSecCSR.Margin = new System.Windows.Forms.Padding(0);
this.cmbSecCSR.Name = "cmbSecCSR";
this.cmbSecCSR.Size = new System.Drawing.Size(184, 21);
this.cmbSecCSR.TabIndex = 2;
this.cmbSecCSR.ValueMember = "Username";
this.cmbSecCSR.TextChanged += new System.EventHandler(this.comboBox_TextChanged);
this.cmbSecCSR.Enter += new System.EventHandler(this.cmbBox_Entered);
//
// csrBindingSource2
//
this.csrBindingSource2.DataMember = "CSR";
this.csrBindingSource2.DataSource = this.productionDS;
//..............
}
Above are the bits and pieces related to this combobox (I'm just fixing bugs in the application, and a newbie in C#.
The contents related to this combobox in the .CS file are the following:
private void loadDetails()
{
this.productionCrewTableAdapter.FillByProductionID(this.productionDS.ProductionCrew, productionID);
cmbSecCSR.DataBindings.Add("SelectedValue", productionMasterBindingSource, "CSR2", true, DataSourceUpdateMode.OnPropertyChanged);
}
private void comboBox_TextChanged(object sender, EventArgs e)
{
ComboBox cmbx = (ComboBox)sender;
if (cmbx.Equals(cmbCamSupplier))
{
}
else if (cmbx.Equals(cmbLGSupplier))
{
}
if (cmbx.Text.Length > 0) return;
cmbx.ResetText();
cmbx.SelectedIndex = -1;
}
private void cmbBox_Entered(object sender, EventArgs e)
{
ComboBox cmb = (ComboBox)sender;
String txt = cmb.Text;
if (cmb.Name.Contains("CSR"))
{
if (cmb != null)
{
((BindingSource)cmb.DataSource).Filter = (cmbOffice.SelectedIndex > -1 ? "Office = '" + cmbOffice.SelectedValue + "' AND " : "") + "IsCSR=1 AND Status=1";
cmb.Text = txt;
}
}
else if (cmb.Name.Contains("RC"))
{
int department = 0;
if (cmb != null)
{
if (cmb.Name.Contains("Camera"))
department = 2;
else if (cmb.Name.Contains("LG"))
department = 3;
else if (cmb.Name.Contains("Power"))
department = 4;
((BindingSource)cmb.DataSource).Filter = (cmbOffice.SelectedIndex > -1 ? "Office = '" + cmbOffice.SelectedValue + "' AND " : "") + "IsCSR=0 AND Status=1 AND (Department = " + department + " OR Department is null OR Department = 0)";
cmb.Text = txt;
}
}
}
If anyone can help me with this issue that I have been struggling with for a while, I'd really really appreciate it.

At the same time to your call clearing values with
this.cmbSecCSR.Items.Clear()
You have to do a
this.cmbSecCSR.Text = ""
or
this.cmbSecCSR.Text = "Default Text"
To clear the selected text in the combobox.

Related

Multiple combo boxes to query a data table issue

I'm putting together a project that has a form to fill out which then populates a query from a separate data table. It will always only grab one row based on the inputs, which is then used for a price calculation. I have two places in the code using the same setup. The first one uses a single combo box for the query and it works great, but the second part uses two combo boxes to make an "AND" query and I can't figure out why it isn't working, it doesn't seem to recognize the selections and place them into the calculation. Below is the code for that part, any help would be appreciated!
private void plant_AmountTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
try
{
plantamountResult = Convert.ToDecimal(plant_AmountTextBox.Text);
}
catch (Exception)
{
MessageBox.Show("Please enter a valid amount");
}
try
{
DataRowView rowviewpml = material_NameComboBox.SelectedItem as DataRowView;
materialNameSelection = "";
if (rowviewpml != null)
{
materialNameSelection = rowviewpml.Row["Material_Species"] as string;
}
DataRowView rowviewst = stockComboBox.SelectedItem as DataRowView;
stockSelection = "";
if (rowviewst != null)
{
stockSelection = rowviewst.Row["Stock_Type"] as string;
}
string mcSearch = "Material_Species = '" + materialNameSelection + "' AND Stock_Type = '" + stockSelection + "'";
Plant_Material_PricingTableAdapter pmpTA = new Plant_Material_PricingTableAdapter();
DataTable pmpDT = pmpTA.GetData();
DataRow[] pmpRow = pmpDT.Select(mcSearch);
foreach(DataRow row in pmpRow)
{
materialEstCost = Convert.ToDouble(pmpRow[0]["Previous_FY_Quotes"]);
}
plantestCostCalc.Text = "$" + ((decimal)materialEstCost * plantamountResult).ToString();
}
catch
{
plantestCostCalc.Text = "0";
}
}

Form display message when all items have been deleted from list

I am trying to delete items from a list that populates from a drop down list and want the to display a message saying there are no items in the list once all items have been deleted.
The lines commented out should make it work however I cant seem to to get i right.
If anyone could help that would be appreciated.
Thanks in advance.
public partial class DeleteBook : System.Web.UI.Page
{
public Catalogue catalogueInstance = new Catalogue();
//Filepath for json file
const string FILENAME =
#"C:\Users\tstra\Desktop\19456932_CSE2ICX_Assessment_3\Bin\Books.json";
protected void Page_Load(object sender, EventArgs e)
{
string jsonText = File.ReadAllText(FILENAME);
// reading data contained in the json filepath
//convert objects in json file to lists
catalogueInstance = JsonConvert.DeserializeObject<Catalogue>(jsonText);
if (IsPostBack) return;
ddlDelete.DataSource = catalogueInstance.books;
ddlDelete.DataTextField = "title";
ddlDelete.DataValueField = "id";
ddlDelete.Items.Insert(0, "There are no items in the Catalogue to
Display");
//binding the data to Drop Down List
ddlDelete.DataBind();
}
protected void ddlDelete_SelectedIndexChanged(object sender, EventArgs e)
{
string jsonText = File.ReadAllText(FILENAME);
// reading data contained in the json filepath
//convert objects in json file to lists
catalogueInstance = JsonConvert.DeserializeObject<Catalogue>(jsonText);
Book b = catalogueInstance.books[ddlDelete.SelectedIndex - 1];
txtID.Text = b.id.ToString();
txtTitle.Text = b.title;
txtAuthor.Text = b.author;
txtYear.Text = b.year.ToString();
txtPublisher.Text = b.publisher;
txtISBN.Text = b.isbn;
}
protected void btnDelete_Click(object sender, EventArgs e)
{
// Get the catalogue instance again (gone stale)
Catalogue catalogueInstance = new Catalogue();
// get the book id.
ddlDelete.DataSource = catalogueInstance.books;
// Get the book.
Book b = catalogueInstance.books[ddlDelete.SelectedIndex - 1];
txtID.Text = b.id.ToString();
txtTitle.Text = b.title;
txtAuthor.Text = b.author;
txtYear.Text = b.year.ToString();
txtPublisher.Text = b.publisher;
txtISBN.Text = b.isbn;
// Delete the book from catalogue instance
catalogueInstance.books.RemoveAt(ddlDelete.SelectedIndex - 1);
ddlDelete.SelectedIndex = 0;
// serialise and write catalogue instance to file.
catalogueInstance.books.RemoveAt(ddlDelete.SelectedIndex - 1);
ddlDelete.SelectedIndex = 0;
// rebind the ddl.
ddlDelete.DataBind();
int id = Int32.Parse(txtID.Text);
Book book = catalogueInstance.books.SingleOrDefault(b => b.id == id);
//catalogueInstance.books.Remove(book);
catalogueInstance.books.RemoveAt(ddlDelete.SelectedIndex - 1);
ddlDelete.SelectedIndex = 0;
//ddlDelete_SelectedIndexChanged(ddlDelete, new EventArgs());
if (book != null)
{
book.title = txtTitle.Text;
book.year = Int32.Parse(txtYear.Text);
book.author = txtAuthor.Text;
book.publisher = txtPublisher.Text;
book.isbn = txtISBN.Text;
string jsonText = JsonConvert.SerializeObject(catalogueInstance);
File.WriteAllText(FILENAME, jsonText);
}
txtSummary.Text = "Book ID of " + id + " has Been deleted from the
Catalogue" + Environment.NewLine;
if (!catalogueInstance.books.Any())
{
txtSummary.Text = "There are no items in the Catalogue";
}
}
}
I suppose that exception is never thrown cause your file always exists. Removing all items from the file doesn't mean that the file will be removed as well. You need to change your code a bit. You can either check catalogueInstance.books that it doesn't have any books or check File.ReadAllText(FILENAME);. I would check the 1 one:
if(!catalogueInstance.books.Any()){
txtSummary.Text = "There are no items in the Catalogue";
}
So you can remove your try-catch block.

datagridview dont let me change the values of the celll

I'm new in c# , but i can do the basics. i need to change all the values of a column and then update the datagrid. The values are in 20170202 format and i want them like 2017-02-02. the method i did works fine but when i try to set the value to the column it wont change.
here is the code:
private void fixAlldates(DataGridView dataGridView2)
{
string aux1 = "";
for (int x = 0; x < dataGridView2.Rows.Count; x++)
{
if (dataGridView2.Rows[x].Cells[4].Value.ToString() != null)
{
aux1 = dataGridView2.Rows[x].Cells[4].Value.ToString();
dataGridView2.Rows[x].Cells[4].Value = fixDate(aux1);
}
if (dataGridView2.Rows[x].Cells[5].Value.ToString() != null)
{
dataGridView2.Rows[x].Cells[5].Value = fixDate(dataGridView2.Rows[x].Cells[5].Value.ToString());
}
dataGridView2.Refresh();
MessageBox.Show(fixDate(aux1); ----> shows result like i want ex: 2017-02-02
MessageBox.Show(dataGridView2.Rows[x].Cells[4].Value.ToString()); ----> shows 2070202
}
}
private string fixDate(string p)
{
if (p == null) return "No especificado";
String fecha = "" + p.Substring(0, 4) + "-" + p.Substring(4, 2) + "-" + p.Substring(6, 2) + "";
return fecha;
}
sorry for my bad english , im a little bit rusty
Edit:
I fill the data with bindingSource.
private void LlenarProductos(string rut)
{
this.rut = rut;
POLbindingSource1.DataSource = null;
dataGridView2.DataSource = null;
DataClasses1DataContext dc = new DataClasses1DataContext();
dc.CommandTimeout = 0;
System.Data.Linq.Table<ASE_PRODUCTOASEGURADO> producto = dc.GetTable<ASE_PRODUCTOASEGURADO>();
var todoprod = from p in producto
where p.RUT == int.Parse(rut)
select new
{
p.POLIZA,
p.SOCIO,
p.SUCURSAL,
p.COD_PROPUESTA,
p.FECHA_ALTA_COTI,
p.FECHA_ALTA_VCTO,
p.NOMBRE_PRODUCTO
};
POLbindingSource1.DataSource = todoprod; // binding source
dataGridView2.DataSource = POLbindingSource1; // filll
this.dataGridView2.Columns["POLIZA"].HeaderText = "Poliza";
this.dataGridView2.Columns["Socio"].HeaderText = "Socio";
this.dataGridView2.Columns["Sucursal"].HeaderText = "Sucursal";
this.dataGridView2.Columns["COD_PROPUESTA"].HeaderText = "Propuesta";
this.dataGridView2.Columns["FECHA_ALTA_COTI"].HeaderText = "Fecha Cotizacion";
this.dataGridView2.Columns["FECHA_ALTA_VCTO"].HeaderText = "Fecha Vencimiento";
this.dataGridView2.Columns["NOMBRE_PRODUCTO"].HeaderText = "Producto";
// fixAlldates(dataGridView2);
}
From msdn https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcell.value(v=vs.110).aspx.
The Value property is the actual data object contained by the cell.
So basically the line MessageBox.Show(dataGridView2.Rows[x].Cells[4].Value.ToString()); is getting the value of the underlying data, whereas MessageBox.Show(fixDate(aux1); is actually formatting the date as you require.
You're overlooking the fact that although you're seeing the data in the grid in a specific way, you're not actually changing the data itself.
UPDATE
To actually edit the data in a cell see here

how to retrieve object on click of particular row in tableLayout in xamarin C#

i am trying to create a tablelayout,where data from service get binded to rows of table.Here i want these things to happen
1.)First row of tablelayout should be Default given(that is "Select item" in my case).
2.)Onclick of any particular row i should be able to retrieve that particular object value.
3.)to put red color divider between rows
below is my code used
TableLayout tl = FindViewById<TableLayout>(Resource.Id.maintable);
var client = new RestClient("http://sitemakong.net/");
var request = new RestRequest("Service/HeadingSearch", Method.POST);
request.RequestFormat = DataFormat.Json;
List<TableHeading> tableItems = client.Execute<List<TableHeading>>(request).Data;
int countValue = tableItems.Count;
TableHeading Tablevalues = new TableHeading();
for (int i = 0; i < countValue; i++)
{
tableItems[0] = new TableHeading { HeadingID = 1, Heading = "_select_", SubHeading = "Hi"};
Tablevalues = tableItems[i];
var Heading = Tablevalues.Heading;
id = Heading;
//Create a new row to be added.
tr = new TableRow(this);
tr.Id = i;
int rowId = tr.Id;
tr.SetTag(Resource.Id.rowId, tr);
tv = new TextView(this);
createView(tr, tv, id.ToString());
tl.AddView(tr);
}
}
//Method
private void createView(TableRow tr, TextView t, String viewdata)
{
t.SetText(viewdata, TextView.BufferType.Editable);
//You have to use Android.Graphics.Color not System.ConsoleColor;
t.SetTextColor(Color.Blue);
t.SetBackgroundColor(Color.Cyan);
t.SetPadding(5, 0, 0, 0);
tr.SetPadding(0, 1, 0, 1);
tr.SetBackgroundColor(Color.Black);
tr.Clickable = true;
tr.AddView(t); // add TextView to row.
}
public void HandleClick(object sender, EventArgs e)
{
var clickedTableRow = sender as TableRow;
// string strval = clickedTableRow.gett;
int s = clickedTableRow.Id;
var tag = clickedTableRow.GetTag(s);
//GET TEXT HERE
// Toast.MakeText(this, tag + " hi string " + strval, ToastLength.Long).Show();
Toast.MakeText(this, tag + " hi " + s, ToastLength.Long).Show();
}
I am new to xamarin and c#.Any help appreciated.
public void HandleClick(object sender, EventArgs e)
{
var clickedTableRow = sender as TableRow;
int s = clickedTableRow.Id;
// s is the index of the row, so just retrieve the matching object
// from the data source
var selected = tableItems[s];
}
to create the "special" row at the start of your table, you could just create a dummy element at the start of your datasource
List<TableHeading> tableItems = client.Execute<List<TableHeading>>(request).Data;
// create a dummy TableHeading, insert it at the start of the list
tableItems.Insert(0, new TableHeading { .. set the appropriate properties here .. });
int countValue = tableItems.Count;
then let your for loop execute and build the table - you will need to remove the line tableItems[0] = ...

how to trigger a "panel update controls" when underlying dataset changes

currently I have a datatable that is ordered by an 'enablelocation' field as a user can add items and reposition them. this datatable is then used to create user controls that are added to a panel.
Currently we are clearing the controls and then rebuilding the panel each time there is a change (whih isn't often, but it still happens) so I am looking for a way of updating the controls on the panel when there is a change.
the current code is this:
private void UpdateCats(int formid) {
//update dataset
cassess.Tables["CaseAssessDefCats"].Clear();
DataTable tcats = Requests.SQLGen.ProcessSQLCommand(gobj, null, "select id,name,shownohistory, case when EnableLocation is null then 1 else EnableLocation end as EnableLocation,FormID from CaseAssessDefCats where EnableLocation >= 0 and FormID = " + formid + " order by EnableLocation, Name", false, true);
if (tcats != null && tcats.Rows.Count > 0) {
tcats.TableName = "CaseAssessDefCats";
cassess.Merge(tcats);
}
//end update dataset
try {
if (_processing) { //check if update is running
return;
}
ClearAssessment(); //removes all the controls
_processing = true;
panMain.Refresh();
panMain.SuspendLayout();
//loop through datatable, re-adding them as controls
for (int a = cassess.CaseAssessDefCats.Rows.Count - 1; a >= 0; a--) {
trow = cassess.CaseAssessDefCats[a];
tcat = new CaseAssessDefCat(cassess, trow, gobj);
tcat.Tag = trow.ID;
tcat.catUp += new EventHandler(CatUp);
tcat.catDown += new EventHandler(CatDown);
tcat.catDelete += new EventHandler(CatDelete);
tcat.catEnter += new EventHandler(CatEnter);
tcat.catLeave += new EventHandler(CatLeave);
tcat.catEdit += new EventHandler(CatEdit);
tcat.catNew += new EventHandler(CatNew);
panMain.Controls.Add(tcat);
tcat.Dock = DockStyle.Top;
}
panMain.ResumeLayout();
_processing = false;
return;
} catch {
panMain.ResumeLayout();
_processing = false;
return;
}
}

Categories

Resources