How to update datagridview with multithreading - c#

i'm new to this multithreading concept and have spent lot of time doing my RnD but not able to get thing done. What I'm trying to do is similar to trading applications . I have A datagridview in windows form showing multiple records in it coming from sql database. it has 4 columns(decimal values).I also have txt files which are updated every minute. I have to read latest line from txt file and compare a decimal values from this line to every decimal column in datagridview. Based on this comparison i'm trying to change color of gridview cells. I find my code logically correct but somehow it's not working.For every row in grid one thread should start but only one thread is started that is for last record in grid.I have attached my code .please help me with this.
**InitiateAlert :: It should loop over grid and start a new thread for each record.
checkiftargetreached :: Each Thread should call this function with parameters. Here the comparison of decimal values is doen and grid cell color is set.**
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace MultithredingSample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnshow_Click(object sender, EventArgs e)
{
DataSet ds = new DataSet();
DataTable dt = new DataTable("MyTable");
dt.Columns.Add(new DataColumn("id", typeof(int)));
dt.Columns.Add(new DataColumn("Val1", typeof(decimal)));
dt.Columns.Add(new DataColumn("Val2", typeof(decimal)));
dt.Columns.Add(new DataColumn("Val3", typeof(decimal)));
dt.Columns.Add(new DataColumn("Flag", typeof(Boolean)));
DataRow dr = dt.NewRow();
dr["id"] = 1;
dr["Val1"] = 23104.10;
dr["Val2"] = 23154.10;
dr["Val3"] = 23845.45;
dr["Flag"] = true;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["id"] = 2;
dr["Val1"] = 25104.10;
dr["Val2"] = 25154.10;
dr["Val3"] = 25845.45;
dr["Flag"] = true;
dt.Rows.Add(dr);
dataGridView1.DataSource = dt;
}
private void checkiftargetreached(Int32 rowid,decimal val1,decimal val2, decimal val3, string filepath)
{
string line;
try
{
while (Convert.ToInt16(this.dataGridView1.Rows[rowid].Cells["Flag"].Value) == 1)
{
FileStream fs = new FileStream("C:\\Users\\username\\Downloads\\" + filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs);
DataTable dtrec = new DataTable();
line = sr.ReadLine();
string[] values = line.Split(',');
for (int i = 0; i <= values.Length - 1; i++)
{dtrec.Columns.Add(values[i]);}
line = sr.ReadLine();
DataRow dr = dtrec.NewRow();
string[] values2 = line.Split(',');
for (int i = 0; i <= values2.Length - 1; i++)
{dr[i] = values2[i];}
dtrec.Rows.Add(dr);
if(Convert.ToDecimal(dtrec.Rows[0][1]) == Convert.ToDecimal(this.dataGridView1.Rows[rowid].Cells["Val1"].Value))
{
if (this.dataGridView1.InvokeRequired){
this.dataGridView1.BeginInvoke((MethodInvoker)delegate () { this.dataGridView1.Rows[rowid].Cells["Val1"].Style.BackColor = Color.Aqua; });
}
}
else if (Convert.ToDecimal(dtrec.Rows[0][1]) == Convert.ToDecimal(this.dataGridView1.Rows[rowid].Cells["Val2"].Value))
{
if (this.dataGridView1.InvokeRequired)
{
this.dataGridView1.BeginInvoke((MethodInvoker)delegate () { this.dataGridView1.Rows[rowid].Cells["Val2"].Style.BackColor = Color.Aqua; this.dataGridView1.Rows[rowid].Cells["Flag"].Value = 0; });
}
}
else if (Convert.ToDecimal(dtrec.Rows[0][1]) == Convert.ToDecimal(this.dataGridView1.Rows[rowid].Cells["Val3"].Value))
{
if (this.dataGridView1.InvokeRequired)
{
this.dataGridView1.BeginInvoke((MethodInvoker)delegate () { this.dataGridView1.Rows[rowid].Cells["Val3"].Style.BackColor = Color.Aqua; });
}
}
else
{
if (this.dataGridView1.InvokeRequired)
{
this.dataGridView1.BeginInvoke((MethodInvoker)delegate () { this.dataGridView1.Rows[rowid].Cells["Val3"].Style.BackColor = Color.IndianRed; });
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void InitiateAlerts()
{
Int32 row;
decimal val1, val2, val3;
try
{
for (int j = 0; j <= dataGridView1.Rows.Count - 1; j++)
{
if (this.dataGridView1.InvokeRequired)
{
this.dataGridView1.BeginInvoke((MethodInvoker)delegate ()
{
if (Convert.ToInt16(this.dataGridView1.Rows[j].Cells["Flag"].Value) == 1)
{
row = j;
val1 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val1"].Value);
val2 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val2"].Value);
val3 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val3"].Value);
Thread TH = new Thread(() => checkiftargetreached(row, val1, val2, val3, "A" + row.ToString() + ".txt"));
TH.Name = "A" + row.ToString() + ".csv";
TH.Start();
}
});
}
else
{
if (Convert.ToInt16(this.dataGridView1.Rows[j].Cells["Flag"].Value) == 1)
{
row = j;
val1 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val1"].Value);
val2 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val2"].Value);
val3 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val3"].Value);
Thread TH = new Thread(() => checkiftargetreached(row, val1, val2, val3, "A" + row.ToString() + ".txt"));
TH.Name = "A" + row.ToString() + ".csv";
TH.Start();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnthread_Click(object sender, EventArgs e)
{
InitiateAlerts();
}
}
}

Here is a tutorial from microsoft.
MS says you need to use "virtualmode"
https://learn.microsoft.com/en-us/dotnet/framework/winforms/controls/implementing-virtual-mode-wf-datagridview-control#code-snippet-1

Related

I'm trying to pass DataTable to Class and I get this message: Input string was not in a correct format

I am taking an excel file to read the fields and pass it to a class, to be able to enter the DB, when I pass dt.AsEnumerable, it is giving me an error in the "Linea" field. This cell sometimes comes with the $ sign. I think that is what is generating the error, so i am trying to replace the character and then convert it to int, since it is an amount field.
using (var streamExcel = System.IO.File.Create(combineFilePath))
{
await file.CopyToAsync(streamExcel);
}
using (var excelWorkbook = new XLWorkbook(combineFilePath))
{
IXLWorksheet workSheet = excelWorkbook.Worksheet(2);
workSheet.Clear(XLClearOptions.AllFormats);
DataTable dt = new DataTable();
bool firstRow = true;
foreach (IXLRow row in workSheet.Rows())
{
//for row number check
if (firstRow)
{
foreach (IXLCell cell in row.Cells())
{
dt.Columns.Add(cell.Value.ToString());
}
firstRow = false;
}
else
{
//Add rows to DataTable.
dt.Rows.Add();
int i = 0;
foreach (IXLCell cell in row.Cells(1, 50))
{
if (cell.Address.ColumnNumber == 11)
{
workSheet.Cell(11, 11).Style.NumberFormat.Format = "#,##0";
cell.SetDataType(XLDataType.Number);
}
dt.Rows[dt.Rows.Count - 1][i] = cell.CachedValue.ToString();
i++;
}
}
}
try
{
var companys = dt.AsEnumerable().Select(row => new Company
{
Name = row.Field<string>("Nombre"),
Rut = row.Field<string>("Rut"),
Address = row.Field<string>("Dirección"),
AddressNumber = row.Field<string>(#"Nº"),
Location = row.Field<string>("Comuna"),
Region = row.Field<string>("Región"),
Giro = row.Field<string>("Giro Cliente"),
Linea = Convert.ToInt32(row.Field<string>("Monto línea Aprobada").Trim().TrimEnd().Replace(#"$", "")),
Observations = row.Field<string>("Observaciones Comité"),
}).ToList();
UserId = _companyService.AddList(companys);
}
catch (Exception e)
{
}
To visualize where it's failing, you could do something like this:
try{
var companysB = dt.AsEnumerable().Select(row => new
{
Name = row.Field<string>("Nombre"),
LineaRaw = row.Field<string>("Monto línea Aprobada"),
LineaProcessed = row.Field<string>("Monto línea Aprobada").Trim().TrimEnd().Replace(#"$", ""),
})
.ToList();
}
Put a breakpoint on 'companysB' and inspect after it's filled. One or more of the LineaRaw / LineaProcessed will not be a number.
The error was when the "Monto línea Aprobada" cell had a blank value, I did this:
var n = 0;
string cellEmty = "";
foreach (DataRow rowEmpty in dt.Rows)
{
cellEmty = rowEmpty["Monto línea Aprobada"].ToString();
if (string.IsNullOrEmpty(cellEmty))
{
cellEmty = "0";
dt.Rows[n].SetField("Monto línea Aprobada", cellEmty);
}
n++;
}

Get Data From Excel only shows last row

I'm having some issues ASPxGridView on Getting data from Excel file. It's only showing the last data from Excel. I've tried to create custom unbound but got no luck. Tried to make it to the List<> and give it a try, no success. This is my code so far.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using DevExpress.Spreadsheet;
using DevExpress.Spreadsheet.Export;
using System.Data;
string FilePath
{
get { return Session["FilePath"] == null ? String.Empty : Session["FilePath"].ToString(); }
set { Session["FilePath"] = value; }
}
private DataTable GetTableFromExcel()
{
Workbook book = new Workbook();
book.InvalidFormatException += book_InvalidFormatException;
book.LoadDocument(FilePath);
Worksheet sheet = book.Worksheets.ActiveWorksheet;
Range range = sheet.GetUsedRange();
DataTable table = sheet.CreateDataTable(range, false);
DataTableExporter exporter = sheet.CreateDataTableExporter(range, table, false);
exporter.CellValueConversionError += exporter_CellValueConversionError;
exporter.Export();
return table;
}
void book_InvalidFormatException(object sender, SpreadsheetInvalidFormatExceptionEventArgs e)
{
}
void exporter_CellValueConversionError(object sender, CellValueConversionErrorEventArgs e)
{
e.Action = DataTableExporterAction.Continue;
e.DataTableValue = null;
}
protected void Upload_FileUploadComplete(object sender, DevExpress.Web.FileUploadCompleteEventArgs e)
{
FilePath = Page.MapPath("~/XlsTables/") + e.UploadedFile.FileName;
e.UploadedFile.SaveAs(FilePath);
}
public class invoice
{
public string nomor_invoice { get; set; }
}
protected void Grid_CustomCallback(object sender, DevExpress.Web.ASPxGridViewCustomCallbackEventArgs e)
{
if (!String.IsNullOrEmpty(FilePath))
{
DataTable table = GetTableFromExcel(); // Get The Excel
List<object> inv = new List<object>();
List<object> dekl = new List<object>();
List<invoice> invoiceList = new List<invoice>();
for (int i = 1; i < table.Rows.Count; i++)
{
DataRow row = table.Rows[i];
invoice nomorInvo = new invoice();
nomorInvo.nomor_invoice = row[1].ToString();
invoiceList.Add(nomorInvo);
string noDkl = row[0].ToString().ToUpper().Trim();
string[] nomor = noDkl.Split('-');
Decimal cab = decimal.Parse(nomor[0].ToString());
Decimal pmsrn = decimal.Parse(nomor[1].ToString());
Decimal reg = decimal.Parse(nomor[2].ToString());
string dkl = nomor[3].ToString();
Decimal cob = decimal.Parse(nomor[4].ToString());
Decimal bln = decimal.Parse(nomor[5].ToString());
Decimal thn = decimal.Parse(nomor[6].ToString());
string invo_no = row[1].ToString().Trim();
inv.Add(invo_no); // add to the list
inv.ToList();
SSREAS.DL.AE.Upload.dsImportir.APFDPE17Row invc = new DL.AE.Upload.dsImportirTableAdapters.APFDPE17TableAdapter().GetDataByDkinvc(cab, pmsrn, reg, dkl, cob, bln, thn, invo_no).SingleOrDefault();
// This is my select query. I used dataSet
if (invc != null)
{
for (int z = 0; z < inv.Count; z++)
{
odsGrid.SelectParameters["DKKDCB"].DefaultValue = cab.ToString();
odsGrid.SelectParameters["DKKDPS"].DefaultValue = pmsrn.ToString();
odsGrid.SelectParameters["DKRGDK"].DefaultValue = reg.ToString();
odsGrid.SelectParameters["DKDKL"].DefaultValue = dkl;
odsGrid.SelectParameters["DKCOB"].DefaultValue = cob.ToString();
odsGrid.SelectParameters["DKBLN"].DefaultValue = bln.ToString();
odsGrid.SelectParameters["DKTHN"].DefaultValue = thn.ToString();
odsGrid.SelectParameters["DKINVC"].DefaultValue = invo_no;
Grid.DataBind();
}
}
else if (invc == null)
{
return;
}
Grid.DataBind();
}
}
}
I've set breakpoint and 0 error occured, But when I upload the Excel File, It's show only 1 data instead of 2 and its the last row from excel. What is wrong with my code? A help would be appreciated. Thanks!
Persist the table in the cache or session in the page_prerender() event bind the data it will work.

Difficulties with C# + Excel

I have a problem.
I have an Excel File where sometimes the same customer is in 2 rows.
But not always.
Its like:
Click
Now, i want to create a DataGrid in C# which can list this in one row like:
Click
I know it would be easier to change the Excel file, but assume it wouldnt work that way(we get the file like this and we cant change it)
I know i could too just make another Excel File and make it with Excel(already did it this way, but we would need it more as C#)
Now i am at this point:
private void button2_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog() { Filter = "Excel Arbeitsmappe |*.xlsx", ValidateNames = true };
if (ofd.ShowDialog() == DialogResult.OK)
textBox1.Text = ofd.SafeFileName;
Excel.Application excelApp = new Excel.Application();
excelApp.Visible = false;
string filename = ofd.FileName;
Excel.Workbook workbook = excelApp.Workbooks.Open(filename);
Excel.Worksheet worksheet = workbook.Worksheets[1];
dataGridView1.ColumnCount = 2;
dataGridView1.Columns[0].Name = "Number";
dataGridView1.Columns[1].Name = "Street";
int rows = worksheet.UsedRange.Rows.Count;
for (int i = 2; i <= rows; i++)
{
string combinehr = worksheet.Cells[i, 150].Text + worksheet.Cells[i, 151].Text;
dataGridView1.Rows.Add(worksheet.Cells[i,29].Text, combinehr);
}
}
How do i expand it that it works like i want?
I would be so grateful
(sorry for the english)
With a reference to ExcelDataReader, ExcelDataReader.DataSet and DataSetExtensions (.Net) you can read the Excel file pretty easy into a DataSet, then you just have to work with the logic:
Input file:
using System;
using System.Data;
using System.IO;
using System.Linq;
using ExcelDataReader;
public DataTable GetTableFromExcel(string filePath)
{
DataSet ds = new DataSet();
using (var stream = System.IO.File.Open(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
using (var reader = ExcelReaderFactory.CreateReader(stream))
{
ds = reader.AsDataSet();
}
}
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("CustomerNr"));
table.Columns.Add(new DataColumn("Address"));
// Set column names
for (int i = 0; i < ds.Tables[0].Columns.Count; i++)
{
// DataColumn.ColumnName can't be empty when DataColumn is part
// of a DataTable (throws ArgumentException)
string columnName = ds.Tables[0].Rows[0][i].ToString();
if (string.IsNullOrWhiteSpace(columnName))
{
columnName = $"Column{i}";
}
ds.Tables[0].Columns[i].ColumnName = columnName;
}
// Remove the first row containing the headers
ds.Tables[0].Rows.Remove(ds.Tables[0].Rows[0]);
// I don't have the benchmarks with me right now, but I've tested
// DataTable.Select vs DataTable.AsEnumerable.Select many times
// and the AsEnumerable method its faster, that's why you need the
// reference to System.Data.DataSetExtensions
var enumerableTable = ds.Tables[0].AsEnumerable();
// list of unique products
var products = enumerableTable.Select(row => row.Field<string>("Product")).Distinct();
// Add a column for each product
foreach (string product in products)
{
table.Columns.Add(new DataColumn(product));
}
// list of unique customers
var customerNumbers = enumerableTable.Select(row => row.Field<double>("CustomerNr")).Distinct();
foreach (var customerNumber in customerNumbers)
{
DataRow record = table.NewRow();
record["CustomerNr"] = customerNumber;
record["Address"] = enumerableTable.First(row => row.Field<double>("CustomerNr").Equals(customerNumber))[1];
for (int i = 2; i < table.Columns.Count; i++)
{
DataRow product = enumerableTable.FirstOrDefault(row => row.Field<double>("CustomerNr").Equals(customerNumber)
&& row.Field<string>("Product").Equals(table.Columns[i].ColumnName));
// Quantity = 0 if product is null
record[i] = product?["Quantity"] ?? 0;
}
table.Rows.Add(record);
}
return table;
}
Result DataTable:
The same result as #IvanGarcíaTopete via Microsoft.Office.Interop.Excel.
Class ExcelModel for Excel data:
public class ExcelModel
{
public string CustomerNr { get; set; }
public string Address { get; set; }
public string Product { get; set; }
public string Quantity { get; set; }
}
Read Excel and fill out model:
private void OpenReadExcel()
{
var dlg = new OpenFileDialog();
if (dlg.ShowDialog() != DialogResult.OK) return;
var exApp = new Microsoft.Office.Interop.Excel.Application();
Workbook exWbk = exApp.Workbooks.Open(dlg.FileName);
Worksheet wSh = exWbk.Sheets[1];
int k = 2;
Customers.Clear();
while (wSh.Cells[k, 1].Text != "" && wSh.Cells[k, 1].Value != null)
{
var rowExcelModel = new ExcelModel()
{
CustomerNr = wSh.Cells[k, 1].Text,
Address = wSh.Cells[k, 2].Text,
Product = wSh.Cells[k, 3].Text,
Quantity = wSh.Cells[k, 4].Text
};
Customers.Add(rowExcelModel);
k++;
}
exApp.Quit();
}
Generate Data table:
private void GenerateDataTable()
{
// unique products and customers
var products = Customers.Select(x => x.Product).Distinct().ToList();
var customers = Customers.Select(x => x.CustomerNr).Distinct().ToList();
// columns CustomerNr and Address
var dataTable = new System.Data.DataTable();
dataTable.Columns.Add(new DataColumn("CustomerNr"));
dataTable.Columns.Add(new DataColumn("Address"));
// columns for each product
foreach (var product in products)
{
dataTable.Columns.Add(new DataColumn(product));
}
//fill rows for each customers
foreach (var customer in customers)
{
var row = dataTable.NewRow();
row["CustomerNr"] = customer;
row["Address"] = Customers.Where(x => x.CustomerNr == customer).Select(x => x.Address).FirstOrDefault();
foreach (var product in products)
{
var quantity = Customers.Where(x => x.CustomerNr == customer && x.Product == product)
.Select(x => x.Quantity).FirstOrDefault();
row[product] = quantity ?? "0";
}
dataTable.Rows.Add(row);
}
dataGridView1.DataSource = dataTable;
}

How to convert datatable to list<> or array?

I want to get all the data from a table using the code below:
CameraBUS cameraBus = new CameraBUS(); //Contain class provider access to DAO for GetByAllCamera.
DataTable dt = cameraBus.Camera_GetByAllCamera(); //select * from table Camera
foreach (DataRow row in dt.Rows)
{
CameraDTO camera = new CameraDTO(row);
if(camera.IDKhuVuc == 4)
{
OpenCamera(camera.ViTri, camera.TaiKhoan, camera.MatKhau, camera.IP);
}
if(camera.IDKhuVuc == 3)
{
OpenCamera(camera.ViTri, camera.TaiKhoan, camera.MatKhau, camera.IP);
}
}
If camera.IDKhuVuc have 7 rows or more. It's always start StartThead1 and my program stop not working.
Example:
My data has 4 rows, but this code can't get 4 rows of 4 cameras. It only opens the first and last cameras.
When I debug my program, it runs 2 rows (rows 2, 3). But when I run my program, it's not opening camera 2 and camera 3.
I think I should use List<> or array. How could I fix this?
Class OpenCamera():
private void OpenCamera(bool position, string username, string password, string ipAddress)
{
if (!position)
{
axLiveX1.IpAddress = ipAddress;
axLiveX1.UserName = username;
axLiveX1.Password = password;
axLiveX1.DataPort = 5550;
axLiveX1.CommandPort = 4550;
axLiveX1.AudioDataPort = 6550;
axLiveX1.DefaultCam = 8;
axLiveX1.OnGetPicture += new AxLIVEXLib._DLiveXEvents_OnGetPictureEventHandler(axLiveX1_OnGetPicture);
axLiveX1.AutoLogin = true;
if (axLiveX1.Connect())
{
}
axLiveX1.StartGrapImage(true);
axLiveX2.IpAddress = ipAddress;
axLiveX2.UserName = username;
axLiveX2.Password = password;
axLiveX2.DataPort = 5550;
axLiveX2.CommandPort = 4550;
axLiveX2.AudioDataPort = 6550;
axLiveX2.DefaultCam = 8;
axLiveX2.OnGetPicture += new AxLIVEXLib._DLiveXEvents_OnGetPictureEventHandler(axLiveX2_OnGetPicture);
axLiveX2.AutoLogin = true;
axLiveX2.Connect();
axLiveX2.StartGrapImage(true);
}
else
{
axLiveX3.IpAddress = ipAddress;
axLiveX3.UserName = username;
axLiveX3.Password = password;
axLiveX3.DataPort = 5550;
axLiveX3.CommandPort = 4550;
axLiveX3.AudioDataPort = 6550;
axLiveX3.DefaultCam = 8;
axLiveX3.OnGetPicture += new AxLIVEXLib._DLiveXEvents_OnGetPictureEventHandler(axLiveX3_OnGetPicture);
axLiveX3.AutoLogin = true;
axLiveX3.Connect();
axLiveX3.StartGrapImage(true);
axLiveX4.IpAddress = ipAddress;
axLiveX4.UserName = username;
axLiveX4.Password = password;
axLiveX4.DataPort = 5550;
axLiveX4.CommandPort = 4550;
axLiveX4.AudioDataPort = 6550;
axLiveX4.DefaultCam = 8;
axLiveX4.OnGetPicture += new AxLIVEXLib._DLiveXEvents_OnGetPictureEventHandler(axLiveX4_OnGetPicture);
axLiveX4.AutoLogin = true;
axLiveX4.Connect();
axLiveX4.StartGrapImage(true);
}
}
Try something like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Col A", typeof(int));
dt.Columns.Add("Col B", typeof(int));
dt.Columns.Add("Col C", typeof(int));
dt.Rows.Add(new object[] { 1, 2, 3});
dt.Rows.Add(new object[] { 10, 20, 30 });
dt.Rows.Add(new object[] { 100, 200, 300 });
List<DataRow> rows = dt.AsEnumerable().Select(x => x).ToList();
var numbers = dt.AsEnumerable().Select(x => x.ItemArray).ToList();
}
}
}
​
​
You can get data of any cell like this with your original code
foreach (DataRow row in dt.Rows)
{
string colA = (string)row["Col A"];
}​
To Get entire column try something like this
var colA = dt.AsEnumerable().Select(x => x.Field<string>("Col A")).ToList();​

how to resize columns in datagridview in C#

I am using following method to fill datagridview from SQL
public bool _MFillGridView(string pQuery, ref DataGridView _pDgv)
{
using (DataTable dt = new DataTable())
{
using (SqlConnection con = new SqlConnection(_CObjectsofClasses._obj_CConnectionString._MGetConnectionString()))
{
using (SqlCommand cmd = new SqlCommand(pQuery, con))
{
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
_pDgv.DataSource = dt;
_pDgv.Cursor = System.Windows.Forms.Cursors.Default;
}
}
}
foreach (DataColumn DC in dt.Columns)
{
_pDgv.Columns[DC.ColumnName].SortMode = DataGridViewColumnSortMode.NotSortable;
if (DC.DataType == typeof(DateTime))
{
_pDgv.Columns[DC.ColumnName].DefaultCellStyle = new DataGridViewCellStyle { Format = _pDateFormat };
_pDgv.Columns[DC.ColumnName].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
else if (DC.DataType == typeof(decimal))
{
_pDgv.Columns[DC.ColumnName].DefaultCellStyle = new DataGridViewCellStyle { Format = _CObjectsofClasses._obj_CNumbricFunction._MFormatNo("0") };
}
}
}
return true;
}
and here I am using like this;
_MFillGridView("My SQL query here", ref MydatagridviewToFill);
above code works perfectly but I am facing column width problems. I want to to pass column index and DataGridViewAutoSizeColumnMode and column width to resize columns like
coloumn[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
coloumn[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
coloumn[2].Width = 200;
and all other columns which are not provided should be set to AutoSizeMode = DataGridViewAutoSizeColumnMode.NotSet;
please suggest me to what I change in code.
Based on my understanding of your question above, I believe this is what you want?
private void ResizeColumns(DataGridView gridview, int column, int width, DataGridViewAutoSizeColumnMode mode)
{
for (int i = 0; i < gridview.ColumnCount; i++)
{
if (i.Equals(column))
{
gridview.Columns[i].AutoSizeMode = mode;
gridview.Columns[i].Width = width;
}
else
{
gridview.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
}
}
}
Update
Ok still not sure I understand what you are after but I think this may point you in the right direction
public bool _MFillGridView(string pQuery, ref DataGridView _pDgv, int columnIndex, int width)
{
using (var dt = new DataTable())
{
// ... Code to retrieve data from Database ...
for (var i = 0; i < dt.Columns.Count; i++)
{
var column = dt.Columns[i];
if (column.DataType == typeof (DateTime))
_pDgv.Columns[column.ColumnName].DefaultCellStyle = new DataGridViewCellStyle {Format = _pDateFormat};
else if (column.DataType == typeof (decimal))
_pDgv.Columns[column.ColumnName].DefaultCellStyle = new DataGridViewCellStyle {Format = _CObjectsofClasses._obj_CNumbricFunction._MFormatNo("0")};
// Do your DataGridView formatting here
if (_pDgv.Columns[column.ColumnName].Index.Equals(columnIndex)) // Check your Column index on the control
{
_pDgv.Columns[column.ColumnName].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
else
{
_pDgv.Columns[column.ColumnName].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
_pDgv.Columns[column.ColumnName].Width = width;
}
}
}
return true;
}
I solved my problem using #Mo Patel i just change int columnIndex, int width to List columnIndex, List width

Categories

Resources