How to bind a many-to-many relation in WinForms? - c#

I have the following DataSet:
The Product and Part tables can be edited using these DataGridViews:
When the user double-clicks a row in the Products grid, the following form opens:
The left column is supposed to list the parts associated with this product. The right column is supposed to list all the other parts. Using the << and >> buttons, the user should be able to choose which parts belong to the current product.
I have done something similar with a one-to-many relation and it worked perfectly. The code was as follows:
public partial class ProductPartsForm : Form
{
private int _productID;
private DataSet1 _data;
public ProductPartsForm(DataSet1 data, DataRowView productRowView)
{
var productRow = (DataSet1.ProductRow)productRowView.Row;
_productID = productRow.ID;
_data = data;
InitializeComponent();
productBindingSource.DataSource = productRowView;
assignedPartBindingSource.DataSource = productBindingSource;
assignedPartBindingSource.DataMember = "FK_Product_Part";
assignedPartsListBox.DisplayMember = "Name";
unassignedPartBindingSource.DataSource = _data;
unassignedPartBindingSource.DataMember = "Part";
unassignedPartsListBox.DisplayMember = "Name";
unassignedPartBindingSource.Filter = $"isnull(ProductID, 0) = 0";
}
private void assignButton_Click(object sender, EventArgs e)
{
var partRowView = (DataRowView)unassignedPartBindingSource.Current;
var partRow = (DataSet1.PartRow)partRowView.Row;
var productRowView = (DataRowView)productBindingSource.Current;
var productRow = (DataSet1.ProductRow)productRowView.Row;
partRow.ProductRow = productRow;
UpdateUI();
}
private void unassignButton_Click(object sender, EventArgs e)
{
var partRowView = (DataRowView)assignedPartBindingSource.Current;
var partRow = (DataSet1.PartRow)partRowView.Row;
partRow.SetProductIDNull();
UpdateUI();
}
private void UpdateUI()
{
assignedPartsListBox.Refresh();
unassignedPartsListBox.Refresh();
assignButton.Enabled = unassignedPartsListBox.Items.Count > 0;
unassignButton.Enabled = assignedPartsListBox.Items.Count > 0;
}
}
With the many-to-many relation, there are two things I couldn't get to work:
The left column doesn't show the names of the parts. It should display lowercase letters, like the right column; instead, it shows the string System.Data.DataRowView. I want to fix this using some sort of lookup, but I don't know how.
When you press <<, the selected part stays on the right column instead of moving to the left column. If you try to press << again with the same part, you get the following error:
System.Data.ConstraintException: 'Column 'ProductID, PartID' is constrained to be unique. Value '-4, -3' is already present.'
(which is understandable). I think this can be fixed using a filter expression, but I'm not sure how to write it and how to update the right column automatically after every change.
Has anyone done something similar and can help point me in the right direction?

Here's what I finally came up with. The key function is UpdateFilters, which creates a list of part IDs assigned to the current product and then filters the two columns "manually" using the IN and NOT IN operators.
public partial class ProductPartsForm : Form
{
private int _productID;
private DataSet1 _data;
public ProductPartsForm(DataSet1 data, DataRowView productRowView)
{
var productRow = (DataSet1.ProductRow)productRowView.Row;
_productID = productRow.ID;
_data = data;
InitializeComponent();
productBindingSource.DataSource = productRowView;
assignedPartBindingSource.DataSource = _data;
assignedPartBindingSource.DataMember = "Part";
assignedPartsListBox.DisplayMember = "Name";
unassignedPartBindingSource.DataSource = _data;
unassignedPartBindingSource.DataMember = "Part";
unassignedPartsListBox.DisplayMember = "Name";
}
private void ProductPartsForm_Load(object sender, EventArgs e)
{
UpdateFilters();
UpdateUI();
}
private void assignButton_Click(object sender, EventArgs e)
{
var partRowView = (DataRowView)unassignedPartBindingSource.Current;
var partRow = (DataSet1.PartRow)partRowView.Row;
var productRowView = (DataRowView)productBindingSource.Current;
var productRow = (DataSet1.ProductRow)productRowView.Row;
_data.ProductPart.AddProductPartRow(productRow, partRow);
UpdateFilters();
UpdateUI();
}
private void unassignButton_Click(object sender, EventArgs e)
{
var partRowView = (DataRowView)assignedPartBindingSource.Current;
var partRow = (DataSet1.PartRow)partRowView.Row;
var productPartRow = _data.ProductPart
.Single(pp => pp.ProductID == _productID && pp.PartID == partRow.ID);
_data.ProductPart.RemoveProductPartRow(productPartRow);
UpdateFilters();
UpdateUI();
}
private void UpdateFilters()
{
var assignedIds = _data.ProductPart
.Where(pp => pp.ProductID == _productID)
.Select(pp => pp.PartID.ToString());
if (assignedIds.Any())
{
assignedPartBindingSource.Filter = $"ID IN ({string.Join(",", assignedIds)})";
unassignedPartBindingSource.Filter = $"ID NOT IN ({string.Join(",", assignedIds)})";
}
else
{
assignedPartBindingSource.Filter = "FALSE";
unassignedPartBindingSource.RemoveFilter();
}
}
private void UpdateUI()
{
assignedPartsListBox.Refresh();
unassignedPartsListBox.Refresh();
assignButton.Enabled = unassignedPartsListBox.Items.Count > 0;
unassignButton.Enabled = assignedPartsListBox.Items.Count > 0;
}
}

Related

how to filter data in sfDatagrid based on comparison of values between columns C#?

here I use the syncfusion framework, and it hasn't been too long since I've used this framework.
what I mean from my question is:
i have 3 columns. "Product_Name", "Cost_Price", "Sales_Price" and 50 rows of data in it. now i want to implement data filter programmatically with click event on sfButton1 based on value in column "Sales_Price" less than or equal to value in column "Cost_Price". and I only want to display data that has problem with Sales_Price, i.e. when Sales_Price Value <= Cost_Price value.
in the previous experiment I tried using telerik and this is in accordance with what I asked:
private void RAD_GridView_ShowData_CustomFiltering(object sender, GridViewCustomFilteringEventArgs e)
{
e.Visible = (int)e.Row.Cells["Sales_price"].Value <= (int)e.Row.Cells["Cost_price"].Value;
}
private void Btn_ShowFilter_Click(object sender, LinkLabelLinkClickedEventArgs e)
{
RAD_GridView_ShowData.EnableFiltering = true;
RAD_GridView_ShowData.EnableCustomFiltering = true;
RAD_GridView_ShowData.CustomFiltering += new GridViewCustomFilteringEventHandler(RAD_GridView_ShowData_CustomFiltering);
FilterDescriptor descriptor = new FilterDescriptor("Sales_price", FilterOperator.IsGreaterThanOrEqualTo, 0);
RAD_GridView_ShowData.FilterDescriptors.Add(descriptor);
}
but the telerik that I use is only a trial and will expire soon, so I use syncfusion which gives full control with the community license.
this code I got from the sync documentation: but it only filters data in "Stock" column based on value < 0 :
B_1_DGV_Stock.Columns["Stock"].FilterPredicates.Add(new FilterPredicate() { FilterType = FilterType.LessThan, FilterValue = "0" });
This requirement will be achievable by using SfDataGrid’s view filtering concept shown below,
public bool FilterRecords(object o)
{
var item = o as OrderInfo;
if (item != null)
{
if (item.UnitPrice <= item.Quantity)
return true;
}
return false;
}
private void button1_Click(object sender, EventArgs e)
{
sfDataGrid1.View.Filter = FilterRecords;
sfDataGrid1.View.RefreshFilter();
}
For more information related to Programmatic Filtering, please refer to the below user guide documentation link,
UG Link: https://help.syncfusion.com/windowsforms/datagrid/filtering#programmatic-filtering
Also, this is not supported for the DataTable. If you need to achieve the same with the Datatable collection too, it will be possible by using the ExpandoObject shown below,
ExpandoObject:
private DataTable dataTableCollection;
private ObservableCollection<dynamic> dynamicCollection;
public Form1()
{
InitializeComponent();
this.WindowState = FormWindowState.Maximized;
//Gets the data for DataTable object.
dataTableCollection = GetGridData();
//Convert DataTable collection as Dyanamic collection.
dynamicCollection = new ObservableCollection<dynamic>();
foreach (System.Data.DataRow row in dataTableCollection.Rows)
{
dynamic dyn = new ExpandoObject();
dynamicCollection.Add(dyn);
foreach (DataColumn column in dataTableCollection.Columns)
{
var dic = (IDictionary<string, object>)dyn;
dic[column.ColumnName] = row[column];
}
}
DynamicOrders = dynamicCollection;
sfDataGrid1.AutoGenerateColumns = true;
sfDataGrid1.DataSource = DynamicOrders;
}
private ObservableCollection<dynamic> _dynamicOrders;
/// <summary>
/// Gets or sets the dynamic orders.
/// </summary>
/// <value>The dynamic orders.</value>
public ObservableCollection<dynamic> DynamicOrders
{
get
{
return _dynamicOrders;
}
set
{
_dynamicOrders = value;
}
}
public DataTable DataTableCollection
{
get { return dataTableCollection; }
set { dataTableCollection = value; }
}
Filtering concept:
public bool FilterRecords(object o)
{
var emplyeeAge = ((ExpandoObject)o).FirstOrDefault(z => z.Key == "EmployeeAge").Value;
var memmbersCount = ((ExpandoObject)o).FirstOrDefault(z => z.Key == "MemmbersCount").Value;
if (emplyeeAge != null && memmbersCount != null)
{
if (double.Parse(emplyeeAge.ToString()) < (double.Parse(memmbersCount.ToString())))
return true;
}
return false;
}
private void FilterClick(object sender, System.EventArgs e)
{
sfDataGrid1.View.Filter = FilterRecords;
sfDataGrid1.View.RefreshFilter();
}

C# How to shorten Datagridview Selectionchanged code in a clean and proper way of coding

I always wanted my code to be cleaner and readable. I'm here in order to achieve that. Since i'm a beginner, it's better to learn this early. Like calling all of them in a class, I don't want too see these many codes in my form. I hope someone would be able to give me a suggestions and a proper way of doing these.
Here's my code
public partial class SIMSSupplier : UserControl
{
ADDSupplier supply;
ADDPReturns returns;
public SIMSSupplier()
{
InitializeComponent();
}
public DataTable dbdataset;
public DataSet ds = new DataSet();
public string ID = "SPPLR-000";
public int DeliveryID, OrderID, ReturnID;
DataView db;
DataTable dt = new DataTable();
private void Supplierview_SelectionChanged(object sender, EventArgs e)
{
var row = Supplierview.CurrentCell.RowIndex;
SupplierID.Text = Supplierview.Rows[row].Cells[0].Value.ToString();
CompanyName.Text = Supplierview.Rows[row].Cells[1].Value.ToString();
ContactName.Text = Supplierview.Rows[row].Cells[2].Value.ToString();
ContactNumber.Text = Supplierview.Rows[row].Cells[3].Value.ToString();
Date.Text = Supplierview.Rows[row].Cells[4].Value.ToString();
Address.Text = Supplierview.Rows[row].Cells[5].Value.ToString();
Remarks.Text = Supplierview.Rows[row].Cells[6].Value.ToString();
}
private void PurchaseOrder_SelectionChanged(object sender, EventArgs e)
{
var row = PurchaseOrder.CurrentCell.RowIndex;
txt_purchase.Text = PurchaseDeliveries.Rows[row].Cells[0].Value.ToString();
txt_supplier.Text = PurchaseDeliveries.Rows[row].Cells[1].Value.ToString();
txt_item.Text = PurchaseDeliveries.Rows[row].Cells[2].Value.ToString();
txt_date.Text = PurchaseDeliveries.Rows[row].Cells[3].Value.ToString();
txt_quantity.Text = PurchaseDeliveries.Rows[row].Cells[4].Value.ToString();
txt_cost.Text = PurchaseDeliveries.Rows[row].Cells[5].Value.ToString();
txt_amount.Text = PurchaseDeliveries.Rows[row].Cells[6].Value.ToString();
txt_sales.Text = PurchaseDeliveries.Rows[row].Cells[7].Value.ToString();
txt_code.Text = PurchaseDeliveries.Rows[row].Cells[8].Value.ToString();
txt_patient.Text = PurchaseDeliveries.Rows[row].Cells[9].Value.ToString();
}
private void PurchaseDeliveries_SelectionChanged(object sender, EventArgs e)
{
var row = PurchaseDeliveries.CurrentCell.RowIndex;
PurchaseID.Text = PurchaseDeliveries.Rows[row].Cells[0].Value.ToString();
Supplier.Text = PurchaseDeliveries.Rows[row].Cells[1].Value.ToString();
ItemDescription.Text = PurchaseDeliveries.Rows[row].Cells[2].Value.ToString();
Dates.Text = PurchaseDeliveries.Rows[row].Cells[3].Value.ToString();
Quantity.Text = PurchaseDeliveries.Rows[row].Cells[4].Value.ToString();
Unitcost.Text = PurchaseDeliveries.Rows[row].Cells[5].Value.ToString();
Amount.Text = PurchaseDeliveries.Rows[row].Cells[6].Value.ToString();
SalesInvoice.Text = PurchaseDeliveries.Rows[row].Cells[7].Value.ToString();
Codeitems.Text = PurchaseDeliveries.Rows[row].Cells[8].Value.ToString();
Patientname.Text = PurchaseDeliveries.Rows[row].Cells[9].Value.ToString();
}
private void PurchaseReturn_SelectionChanged(object sender, EventArgs e)
{
var row = PurchaseReturn.CurrentCell.RowIndex;
txt_return.Text = PurchaseReturn.Rows[row].Cells[0].Value.ToString();
txt_rsupplier.Text = PurchaseReturn.Rows[row].Cells[1].Value.ToString();
txt_ritem.Text = PurchaseReturn.Rows[row].Cells[2].Value.ToString();
txt_rmodel.Text = PurchaseReturn.Rows[row].Cells[3].Value.ToString();
txt_rsrp.Text = PurchaseReturn.Rows[row].Cells[4].Value.ToString();
txt_rcode.Text = PurchaseReturn.Rows[row].Cells[5].Value.ToString();
txt_rdate.Text = PurchaseReturn.Rows[row].Cells[6].Value.ToString();
txt_rremarks.Text = PurchaseReturn.Rows[row].Cells[7].Value.ToString();
}
}
the first can simplify as the following:
private void Supplierview_SelectionChanged(object sender, EventArgs e)
{
var row = Supplierview.CurrentRow;
SupplierID.Text = row.Cells[0].Value.ToString();
CompanyName.Text = row.Cells[1].Value.ToString();
ContactName.Text = row.Cells[2].Value.ToString();
ContactNumber.Text = row.Cells[3].Value.ToString();
Date.Text = row.Cells[4].Value.ToString();
Address.Text = row.Cells[5].Value.ToString();
Remarks.Text = row.Cells[6].Value.ToString();
}
the second , i would recommend use objects collection as a datasource for your grid. For example :
class DataItem{
public string SupplierID {get;set;}
public string CompanyName {get;set;}
.....
}
Supplierview.DataSource = "collection of DataItem"
then
private void Supplierview_SelectionChanged(object sender, EventArgs e)
{
var dataItem = dataGridView1.CurrentRow.DataBoundItem as DataItem;
if (dataItem != null)
{
SupplierID.Text = dataItem.SupplierID;
.....
}
}
I suggest using DataBinding for this, then there is no code needed to perform the actions in your sample.
If you dont want to use databinding you could simply make use of private methods to organize your code.
For example
#region Supplier Stuff
private void SupplierViewChanged(DataRow row)
{
SupplierID.Text = row.Cells[0].Value.ToString();
CompanyName.Text = row.Cells[1].Value.ToString();
ContactName.Text = row.Cells[2].Value.ToString();
ContactNumber.Text = row.Cells[3].Value.ToString();
Date.Text = row.Cells[4].Value.ToString();
Address.Text = row.Cells[5].Value.ToString();
Remarks.Text = row.Cells[6].Value.ToString();
}
// put all other helper methods that deal with Supplier here...
#endregion Supplier Stuff
private void Supplierview_SelectionChanged(object sender, EventArgs e)
{
SupplierViewChanged(Supplierview.CurrentRow);
}
This makes your code a bit more organized and readable, but databinding is still the method I would choose

How to fix the drag and drop using dev express in c# after fetching data and setting tag property

enter image description here
namespace Implementer
{
public partial class MainForm : Form
{
#region intit and globals
public MainForm()
{
InitializeComponent();
DevExpress.XtraGrid.Views.Grid.GridView gridView = new DevExpress.XtraGrid.Views.Grid.GridView();
var transactions = new ObservableCollection<Item>();
for (int i = 0; i <= 100; i++)
{
transactions.Add(new Item { Content = "Item " + i });
}
grdTransactions.AllowDrop = true;
grdTransactions.DataSource = transactions;
dgmWf.AddingNewItem += (s, e) => transactions.Remove(e.Item.Tag as Item);
}
Point mouseDownLocation;
GridHitInfo gridHitInfo;
#endregion
#region events
public void Mainform_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'vA_ERP4_ADMINDataSet.SYSTEM_MODULES' table. You can move, or remove it, as needed.
//Project initiation
//Fill drop down for project list
cmbProject.SelectedIndex = 0;
DataAccess dataAccess = new DataAccess(GlobalFunctions.GetConnectionString());
DataTable dtResult = dataAccess.ExecuteQueryDataSet("select MODULE_CODE, MODULE_DESC from SYSTEM_MODULES where module_is_active=1").Tables[0];
cmbProject.DisplayMember = "MODULE_DESC";
cmbProject.ValueMember = "MODULE_CODE";
cmbProject.DataSource = dtResult;
}
private void cmbProject_SelectedIndexChanged(object sender, EventArgs e)
{
lblCurrentProject.Text = cmbProject.Text;
if (cmbProject.Text != null)
{
DataAccess dataAccess = new DataAccess(GlobalFunctions.GetConnectionString());
DataTable dtTransactions = dataAccess.ExecuteQueryDataSet("select sys_trans_id, sys_trans_desc1 from WF_SYSTEM_TRANS where MODULE_CODE= '" + cmbProject.Text + "'").Tables[0];
grdTransactions.DataSource = dtTransactions;
}
}
private void btnSalesInvoice_Click(object sender, EventArgs e)
{
int sysTransId = 1001;
FillTransactionDetails(sysTransId);
}
#endregion
#region drag drop
private void grdTransactions_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && CanStartDragDrop(e.Location))
{
StartDragDrop();
}
}
private void grdTransactions_MouseDown(object sender, MouseEventArgs e)
{
gridHitInfo = grdVTransactions.CalcHitInfo(e.Location);
mouseDownLocation = e.Location;
}
private void grdTransactions_MouseLeave(object sender, EventArgs e)
{
if (gridHitInfo != null)
gridHitInfo.View.ResetCursor();
gridHitInfo = null;
}
private bool CanStartDragDrop(Point location)
{
return gridHitInfo.InDataRow && (Math.Abs(location.X - mouseDownLocation.X) > 2 || Math.Abs(location.Y - mouseDownLocation.Y) > 2);
}
public void StartDragDrop()
{
var draggedRow = gridHitInfo.View.GetRow(gridHitInfo.RowHandle) as Item;
var tool = new FactoryItemTool(" ", () => " ", diagram => new DiagramShape(BasicShapes.Rectangle) { Content = draggedRow.Content, Tag = draggedRow }, new System.Windows.Size(150, 100), false);
dgmWf.Commands.Execute(DiagramCommandsBase.StartDragToolCommand, tool, null);
}
#endregion
#region function
private void FillTransactionDetails(int systemTransactionId)
{
//Fill document
//Fill steps
DataAccess dataAccess = new DataAccess(GlobalFunctions.GetConnectionString());
DataTable transactionDetails = dataAccess.ExecuteQueryDataSet("SELECT DOC_TYPE_DESC1 FROM WF_SYSTEM_TRANS_DT WHERE SYS_TRANS_ID=1001 and MODULE_CODE= '" + cmbProject.Text + "'").Tables[0];
transactionDetails.Rows.Add();
grdDocuments.DataSource = transactionDetails;
grdDocuments.Columns["Details"].DisplayIndex = 2;
grdDocuments.Columns["Delete"].DisplayIndex = 2;
DataTable transactionSteps = dataAccess.ExecuteQueryDataSet("select WF_STEP_DESC1 from WF_STEPS where wf_id= 10101 and MODULE_CODE= '" + cmbProject.Text + "'").Tables[0];
transactionSteps.Rows.Add();
grdSteps.DataSource = transactionSteps;
}
#endregion
}
public class Item
{
public string Content { get; set; }
}
}
I don't really know where is the mistake and have been looking at it for the past few days and searching for an answer but no luck so I'd be so happy if you could help me out. It was working without the data fetching. but after calling the data it doesn't work. drag it from the grid view and when it reaches the diagram control it would turn into a rectangle with a tag property of it's ID.. With regards to the connection string.. I created a global function to just call it on the main form.

Textbox autocomplete function not autocompleting in C# WinForm Application

Im having problems with this simple function on a textbox.. I have a winforms application, with a textbox, set up to autocomplete like this:
if (rbSerialNumSearch.Checked)
{
txtSerialNum.Enabled = true;
AutoCompleteStringCollection data = new AutoCompleteStringCollection();
//Test data
data.Add("555-777-333");
data.Add("222-333-444");
data.Add("111-222-333");
txtSerialNum.AutoCompleteCustomSource = data;
txtSerialNum.AutoCompleteMode = AutoCompleteMode.Suggest;
txtSerialNum.AutoCompleteSource = AutoCompleteSource.CustomSource;
}
But it is not working. Nothing appears when i type in the textbox? If i i specify strings directly to the textbox collection property (in design mode), it works fine, but when i try to add strings programmatically, nothing happends?
Thanks in advance..
ENTIRE CODE FOR FORM HERE:
namespace GUI
{
public partial class UpdateEquipmentForm : Form
{
EquipmentManager em;
ProductManager pm;
CategoryManager cm;
public UpdateEquipmentForm()
{
InitializeComponent();
em = new EquipmentManager();
pm = new ProductManager();
cm = new CategoryManager();
}
private void btnSearch_Click(object sender, EventArgs e)
{
if (rbCategorySearch.Checked)
{
List<Equipment> equipments = em.GetAllEquipmentInStock().Where(eq => eq.Product.Category_Id == (int)cbChooseCategory.SelectedValue).ToList();
var resultset = (from eq in equipments
select new { eq.Product.ProductNameNum, eq.Id, eq.SerialNumber, eq.InvoiceNumber, eq.CreatedDate, eq.ExpiryDate, eq.FirstUseDate }).ToList();
dgvResult.DataSource = resultset;
}
if (rbProductsSearch.Checked)
{
List<Equipment> equipments = em.GetAllEquipmentInStock().Where(eq => eq.Product.Id == (int)cbChooseType.SelectedValue).ToList();
var resultset = (from eq in equipments
select new { eq.Product.ProductNameNum, eq.Id, eq.SerialNumber, eq.InvoiceNumber, eq.CreatedDate, eq.ExpiryDate, eq.FirstUseDate }).ToList();
dgvResult.DataSource = resultset;
}
if (rbSerialNumSearch.Checked)
{
List<Equipment> equipments = em.GetAllEquipmentInStock();
var resultset = (from eq in equipments
where eq.SerialNumber.Contains(txtSearchEquipment.Text)
select new { eq.Product.ProductNameNum, eq.Id, eq.SerialNumber, eq.InvoiceNumber, eq.CreatedDate, eq.ExpiryDate, eq.FirstUseDate }).ToList();
dgvResult.DataSource = resultset;
}
}
private void rbCategorySearch_CheckedChanged(object sender, EventArgs e)
{
if (rbCategorySearch.Checked)
{
cbChooseCategory.Enabled = true;
cbChooseCategory.DataSource = cm.GetAllActiveCategories();
cbChooseCategory.DisplayMember = "Name";
cbChooseCategory.ValueMember = "Id";
}
else
{
cbChooseCategory.Enabled = false;
}
}
private void rbProductsSearch_CheckedChanged(object sender, EventArgs e)
{
if (rbProductsSearch.Checked)
{
cbChooseType.Enabled = true;
cbChooseType.DataSource = pm.GetAllActiveProducts();
cbChooseType.DisplayMember = "ProductNameNum";
cbChooseType.ValueMember = "Id";
}
else
{
cbChooseType.Enabled = false;
}
}
private void rbSerialNumSearch_CheckedChanged(object sender, EventArgs e)
{
if (rbSerialNumSearch.Checked)
{
txtSerialNum.Enabled = true;
AutoCompleteStringCollection data = new AutoCompleteStringCollection();
data.Add("555-777-333");
data.Add("222-333-444");
data.Add("111-222-333");
txtSerialNum.AutoCompleteCustomSource = data;
txtSerialNum.AutoCompleteMode = AutoCompleteMode.Suggest;
txtSerialNum.AutoCompleteSource = AutoCompleteSource.CustomSource;
}
else
{
txtSerialNum.Enabled = false;
}
}
}
}
Found the problem.. Really stupid of me. I was referencing the wrong textbox :-( The one i should be referencing is called txtSearchSerial and not txtSerialNum. Doh !
Appreciate the effort guys..thanks.
You can set a break point to
txtSerialNum.Enabled = true;
I think this application never run into this block.
Or after this code, you re-set the binding of txtSerialNum.

objects in datagridview

Im adding objects to a datagridview ( only one kind) through a list
ej.
List<Material> mater = new List<Material>();
DataGridView dgvMAterial = new DataGridView();
dgvMaterial.DataSource = null;
mater.Add((Material)cmbMaterial.SelectedValue);
dgvMaterial.DataSource = mater;
But every time I click over the datagrid I get an indexoutofrangeexeption.
Can somone tell me why?
thanks
here is my whole code for the form
public partial class inicio : Form
{
private string ConnectionString = "Data Source=localhost\\sqlexpress;Initial Catalog=data.mdf;Integrated Security=SSPI;";
//private string ConnectionString = "Server=.\\SQLExpress;AttachDbFilename=|DataDirectory|\\data\\data_data.mdf.mdf; Database=data.mdf;Trusted_Connection=Yes;";
private ISessionFactory sessionFactory;
List<Material> mater = new List<Material>();
List<Salarios> salar = new List<Salarios>();
IBindingList mind = new BindingList<Salarios>();
Productos prod;
public inicio()
{
InitializeComponent();
sessionFactory = nhn.BusinessObjects.Initialize.CreateSessionFactory(ConnectionString);
dgvMaterial.DataSource = mater;
}
private void materialToolStripMenuItem_Click(object sender, EventArgs e)
{
Catalogos.frmMaterial material = new costeos.Catalogos.frmMaterial(ConnectionString);
material.ShowDialog(this);
material.Dispose();
}
private void salariosToolStripMenuItem_Click(object sender, EventArgs e)
{
Catalogos.frmSalarios salarios = new costeos.Catalogos.frmSalarios(ConnectionString);
salarios.ShowDialog(this);
salarios.Dispose();
}
private void agregarToolStripMenuItem_Click(object sender, EventArgs e)
{
Catalogos.frmAddRemuneraciones rem = new costeos.Catalogos.frmAddRemuneraciones(ConnectionString);
rem.ShowDialog(this);
rem.Dispose();
}
private void agregarToolStripMenuItem1_Click(object sender, EventArgs e)
{
Catalogos.frmAddAdmin adm = new costeos.Catalogos.frmAddAdmin(ConnectionString);
adm.ShowDialog(this);
adm.Dispose();
}
private void agregarToolStripMenuItem2_Click(object sender, EventArgs e)
{
Catalogos.frmAddInsumosInd insumos = new costeos.Catalogos.frmAddInsumosInd(ConnectionString);
insumos.ShowDialog(this);
insumos.Dispose();
}
private void txt_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsDigit(e.KeyChar) || char.IsPunctuation(e.KeyChar) || char.IsControl(e.KeyChar))
{
e.Handled = false;
}
else
{
e.Handled = true;
}
}
private void inicio_Load(object sender, EventArgs e)
{
LlenaCampos();
}
private void LlenaCampos()
{
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var mat = session.CreateCriteria(typeof(Material))
.List<Material>();
var sal = session.CreateCriteria(typeof(Salarios))
.List<Salarios>();
transaction.Commit();
cmbMaterial.DataSource = mat;
cmbMaterial.DisplayMember = "Nombre";
cmbSalarios.DataSource = sal;
cmbSalarios.DisplayMember = "Nombre";
cmbMIndirecta.DataSource = sal;
cmbMIndirecta.DisplayMember = "Nombre";
}
}
}
private void btnAddMaterial_Click(object sender, EventArgs e)
{
materialBindingSource.DataSource = null;
//dgvMaterial.DataSource = null;
mater.Add((Material)cmbMaterial.SelectedValue);
//dgvMaterial.DataSource = mater;
dgvMaterial.DataSource = materialBindingSource;
materialBindingSource.DataSource = mater;
materialBindingSource.ResetBindings(false);
}
private void button2_Click(object sender, EventArgs e)
{
dgvSalarios.DataSource = null;
salar.Add((Salarios)cmbSalarios.SelectedValue);
dgvSalarios.DataSource = salar;
}
private void button3_Click(object sender, EventArgs e)
{
dgvMIndirecta.DataSource = null;
mind.Add((Salarios)cmbMIndirecta.SelectedValue);
dgvMIndirecta.DataSource = mind;
}
private void button1_Click(object sender, EventArgs e)
{
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
if (prod == null)
{
prod = new Productos { CargasTurno = float.Parse(txtCargasTurno.Text), CavidadesMolde = int.Parse(txtCavidadesMolde.Text), Clave = txtClave.Text, Comentarios = txtComentarios.Text, MezclasTurno = float.Parse(txtMezclasTurno.Text), Moldes = int.Parse(txtMoldes.Text), Nombre = txtNombre.Text, Peso = float.Parse(txtPesoTotal.Text), TotalPza = int.Parse(txtPzasTotales.Text), Turnos = int.Parse(txtTurnos.Text) };
session.Save(prod);
transaction.Commit();
}
foreach (DataGridViewRow dr in dgvMaterial.Rows)
{
Material m = dr.DataBoundItem as Material;
m.Materiales
PMaterial mat = new PMaterial { Material = dr.DataBoundItem as Material, Cantidad = float.Parse(dr.Cells["Cantidad"].Value.ToString()), Fecha = DateTime.Now, Producto = prod };
session.Save(mat);
}
transaction.Commit();
session.Close();
}
}
}
}
}
That's probably not DGV problem, but with this combo box. Show us the code that fills combo box and sets its properties.
If you are casting to Material class you should probably use SelectedItem instead of SelectedValue. (unless you exactly know what you're doing)
I would guess that you have an event-handler that isn't happy. What exactly does the message say?
You might also be having problems if you are adding the same Material instance to the list multiple times; since IndexOf will only find the first occurrence. This line makes me very suspicious:
mater.Add((Material)cmbMaterial.SelectedValue);
since it could potentially (on consecutive clicks / etc) do exactly this.
Note: if you used BindingList<T> instead all you'd have to doo is Add(...) - no resetting required:
field:
BindingList<Material> mater = new BindingList<Material>();
init grid:
dgvMaterial.DataSource = mater;
add item:
mater.Add(newInstance);
If you assign data source to the DGV you should check element count - if zero then assign null. I don't know why this is the way it is, but I'm doing it in all my forms.
//I'm still analysing the rest of the code

Categories

Resources