Add blank row programatically in XrTable (XtraReport)? - winforms

I have 6 records of data and want to add 4 blank rows more to make a list of 10 rows in the run-time. What must I do?

For data source modification procedure in the BeforePrint event.. Refer to the sample code snippet:
void report1_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) {
DataDataSet ds = new DataDataSet();
this.sitE_SummaryTableAdapter1.Fill(ds.SITE_Summary);
foreach (DataDataSet.SITE_SummaryRow row in ds.SITE_Summary) {
double val = Convert.ToDouble(row["SITE_Summary.Heating_Energy_Transfer"]);
row["SITE_Summary.Heating_Energy_Transfer"] = convertTemperature(val, true);
}
this.report1.DataSource = ds;
}

Related

Unable To Show Image In Picture Box Control From SQL Server Database In Windows Form Application

I want to add scanned images (Vehicle Documents) to SQL Server Database from my C# Windows Form Application. In the SQL Server database, the datatype for the column where scanned documents will be saved is Image where I want to store the image as an array for each scanned document. Here is my code that saves the data into the SQL Server database.
Browse Button Code:
private void btnBrowseFiles_Click(object sender, EventArgs e)
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Filter = "image files|*.jpg;*.png;*.gif;*.icon;*.bmp;*.*";
DialogResult dResult = fileDialog.ShowDialog();
if (dResult == DialogResult.OK)
{
pBoxVehicleDocument.Image = Image.FromFile(fileDialog.FileName);
}
}
Add Button Code:
private void btnAdd_Click(object sender, EventArgs e)
{
string documentName, vehicleId;
documentName = txtDocumentName.Text;
vehicleId = lblVehicleId.Text;
MemoryStream mStream = new MemoryStream();
pBoxDocument.Image.Save(mStream, System.Drawing.Imaging.ImageFormat.Jpeg);
mStream.ToArray();
//The documentName, vehicleId and imageArray to be passed to AddVehicleDocuments Method within Vehicles Class.
//No I am getting invalid arguments exception on AddVehicleDocuments() method.
Vehicles.AddVehicleDocuments(documentName, vehicleId, imageArray);
}
And Finally the AddVehicleDocuments Method Code within Vehicles Class:
public static void AddVehicleDocuments(string documentName, int vehicleId, byte[] imageString)
{
string query = string.Format("insert into tblDocuments values ('{0}', {1}, {3})", documentName, vehicleId, imageString);
DataAccess.Execute(query);
}
Now, the following code is for image selection. I am not sure how can I convert the array values from the database back to a Picture Box on the Windows Form:
private void childDocumentDetails_Load(object sender, EventArgs e)
{
int documentId = Convert.ToInt32(lblDocumentId.Text);
DataRow dr = Vehicles.GetDocumentDetailsById(documentId);
txtDocumentName.Text = dr["DocumentName"].ToString();
txtVehicleNo.Text = dr["VehicleNo"].ToString();
//here the image array from the database will locate in dr["VehicleDocument"];
pBoxDocument.Image = //Need to write my code here
}
The DataRow dr contains all of the three records for the given document i.e. DocumentName, VehicleNo/VehicleID, and the byte string but the Picture Box Control still do not show the target image. Just need some expert suggestion in this regard.
Any help will be highly appreciated.
Because I was sure as per my research, that the Image data type on SQL Server-Side will work for me to store scanned documents for a vehicle. However, I modified my code later and used Verbinary(MAX) as the data type for storing images in the database.
I modified my insertion code which now looks like this:
private void btnAdd_Click(object sender, EventArgs e)
{
string documentName, vehicleId;
documentName = txtDocumentName.Text;
vehicleId = lblVehicleId.Text;
MemoryStream mStream = new MemoryStream();
pBoxDocument.Image.Save(mStream, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] imagesBytes = mStream.ToArray();
Vehicles.AddVehicleDocuments(documentName, vehicleId, imagesBytes);
}
And the image selection code looks like:
private void childDocumentDetails_Load(object sender, EventArgs e)
{
int documentId = Convert.ToInt32(lblDocumentId.Text);
DataRow dr = Vehicles.GetDocumentDetailsById(documentId);
txtDocumentName.Text = dr["DocumentName"].ToString();
txtVehicleNo.Text = dr["VehicleNo"].ToString();
byte[] imageString = (byte[]dr["VehicleDocument"]);
MemoryStream mStream = new MemoryStream(imageString);
pBoxDocument.Image = Image.FromStream(mStream);
}
Thanks to #Jimi for suggesting code modifications.

How to display Object data in a TableLayoutPanel in a performant way

I have written the folowing code to populate the data from a object in a tablelayoutpanel control. It works Smile | :) , but when its loading the data onto the table, it flickers/jumps for few seconds and then after 2-3 seconds when its done processing the data it populates the data Frown | :( . I believe this behaviour is because of the code written for dynamically processing & drawing of the various controls in the table based on the object data.
I need your help in optimising the code/improving the performance of this code so that the table can load smoothly and fast. Please help. Thanks.
PS: This code is written for a table containing small amount of data. But going forward the same is planned for populating table with 4X more data. If this is the case, then performance will be very poor, which worries me. Please suggest some ideas.
private void button1_Click(object sender, EventArgs e)
{
Common obj = new Common();
obj.CreateDeserializedXmlObject(#"E:\TestReport.xml");
var v = obj.GetAdminData();
tableLayoutPanel1.ColumnCount = 4;
tableLayoutPanel1.RowCount = ((v.DOCREVISIONS.Length * 4) + 1 + (v.USEDLANGUAGES.L10.Length));
Label labelLanguage = new Label();
Label labelUsedLanguage = new Label();
Label labelDocRevisions = new Label();
labelLanguage.Text = "Language:";
labelUsedLanguage.Text = "Used Language:";
labelDocRevisions.Text = "Doc-Revisions:";
ComboBox comboBoxLanguage = new ComboBox();
comboBoxLanguage.Items.Add(v.LANGUAGE.Value.ToString());
comboBoxLanguage.SelectedIndex = 0;
ComboBox comboBoxUsedLanguage = new ComboBox();
foreach (LPLAINTEXT Lang in v.USEDLANGUAGES.L10)
{
comboBoxUsedLanguage.Items.Add(Lang.L.ToString());
}
comboBoxUsedLanguage.SelectedIndex = 0;
int index = 0;
Label[] labelDocRevision = new Label[v.DOCREVISIONS.Length];
Label[] labelRevision = new Label[v.DOCREVISIONS.Length];
Label[] labelState = new Label[v.DOCREVISIONS.Length];
Label[] labelTeamMember = new Label[v.DOCREVISIONS.Length];
Label[] labelDate = new Label[v.DOCREVISIONS.Length];
TextBox[] textBoxRevision = new TextBox[v.DOCREVISIONS.Length];
TextBox[] textBoxState = new TextBox[v.DOCREVISIONS.Length];
TextBox[] textBoxTeamMember = new TextBox[v.DOCREVISIONS.Length];
TextBox[] textBoxDate = new TextBox[v.DOCREVISIONS.Length];
foreach (DOCREVISION dcr in v.DOCREVISIONS)
{
labelDocRevision[index] = new Label();
labelRevision[index] = new Label();
labelState[index] = new Label();
labelTeamMember[index] = new Label();
labelDate[index] = new Label();
textBoxRevision[index] = new TextBox();
textBoxState[index] = new TextBox();
textBoxTeamMember[index] = new TextBox();
textBoxDate[index] = new TextBox();
labelDocRevision[index].Text = "DOCREVISION["+index.ToString()+"]:";
labelRevision[index].Text = "Revision:";
labelState[index].Text = "State:";
labelTeamMember[index].Text = "TeamMemberRef:";
labelDate[index].Text = "Date:";
textBoxRevision[index].Text = dcr.REVISIONLABEL.Value.ToString();
textBoxState[index].Text = dcr.STATE.Value.ToString();
textBoxTeamMember[index].Text = dcr.TEAMMEMBERREF.Value.ToString();
textBoxDate[index].Text = dcr.DATE.Value.ToString();
index++;
}
// Add child controls to TableLayoutPanel and specify rows and column
tableLayoutPanel1.Controls.Add(labelLanguage, 0, 0);
tableLayoutPanel1.Controls.Add(labelUsedLanguage, 0, 1);
tableLayoutPanel1.Controls.Add(labelDocRevisions, 0, 2);
tableLayoutPanel1.Controls.Add(comboBoxLanguage, 1, 0);
tableLayoutPanel1.Controls.Add(comboBoxUsedLanguage, 1, 1);
int docRevRowSpacing = 2;
for (int loop = 0; loop < index; loop++)
{
tableLayoutPanel1.Controls.Add(labelDocRevision[loop], 1, docRevRowSpacing);
tableLayoutPanel1.Controls.Add(labelRevision[loop], 2, docRevRowSpacing);
tableLayoutPanel1.Controls.Add(labelState[loop], 2, docRevRowSpacing+1);
tableLayoutPanel1.Controls.Add(labelTeamMember[loop], 2, docRevRowSpacing+2);
tableLayoutPanel1.Controls.Add(labelDate[loop], 2, docRevRowSpacing+3);
tableLayoutPanel1.Controls.Add(textBoxRevision[loop], 3, docRevRowSpacing);
tableLayoutPanel1.Controls.Add(textBoxState[loop], 3, docRevRowSpacing+1);
tableLayoutPanel1.Controls.Add(textBoxTeamMember[loop],3 , docRevRowSpacing+2);
tableLayoutPanel1.Controls.Add(textBoxDate[loop], 3, docRevRowSpacing+3);
docRevRowSpacing += 4;
}
tableLayoutPanel1.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
Controls.Add(this.tableLayoutPanel1);
}
There are two minor changes that helps a little bit.
At the start of your code you can call SuspendLayout. This prevents the TableLayoutPanel to redraw itself every time you add a control to it. When you're done adding all controls at the end you call ResumeLayout. At that moment the TableLayoutPanel will redraw only once. It still takes time but at least most the flickering is gone. At the end of your example code you add the tableLayoutPanel1 again to the forms control collection. If the TableLayoutPanel is on your form designer you don't need that and by doing it you make your performance worse because now you have two tableLayoutPanels that need to be painted.
private void button1_Click(object sender, EventArgs e)
{
tableLayoutPanel1.SuspendLayout();
// all your other code goes here
// not sure why you add the tableLayouyPanel AGAIN to the
// form control collection.
// Controls.Add(this.tableLayoutPanel1);
tableLayoutPanel1.ResumeLayout();
}
I noticed in my testing that resizing the form gives the same flickering effect. I used the ResizeBegin and ResizeEnd events to do the same Suspend and Resume layout trick:
private void Form1_ResizeBegin(object sender, EventArgs e)
{
tableLayoutPanel1.SuspendLayout();
}
private void Form1_ResizeEnd(object sender, EventArgs e)
{
tableLayoutPanel1.ResumeLayout();
}
This as much as you can do with your current code (except maybe the use of all those arrays with controls but their overhead is not the major issue here).
The TableLayoutPanel is maybe not the best control for what you want to achieve. It lacks for example VirtualMode support, something the DataGridView does. That would enable you to only load and show data that is visible on the form (and therefor create controls for it). Adapting your code to use that control is left as an exercise for the reader and if new issues pop-up feel free to start a new question.

Getting data from detail row

How can i get data from devexress gridcontrol's detail row via double-click.
If i focused on child row gridview's double click event doesn't catch.
i tried this method, but my request is catching data by double click
private void gcOperasyonlar_FocusedViewChanged(object sender, DevExpress.XtraGrid.ViewFocusEventArgs e)
{
if (e.View != null && e.View.IsDetailView)
(e.View.ParentView as GridView).FocusedRowHandle = e.View.SourceRowHandle;
GridView detailView = gcOperasyonlar.FocusedView as GridView;
MessageBox.Show(detailView.GetFocusedRowCellValue("Kalip").ToString());
}
thanks for your help
There is also an easier way:
ColumnView cv = _gridControlxyz.FocusedView as ColumnView;
selectedRow row = cv.GetRow(cv.FocusedRowHandle)
I found this code on the forum, It might be useful as long as your grid is not editable (so that mouse click doesn't activate the editable field).
private void gridView1_DoubleClick(object sender, EventArgs e) {
GridView view = (GridView)sender;
Point pt = view.GridControl.PointToClient(Control.MousePosition);
DoRowDoubleClick(view, pt);
}
private static void DoRowDoubleClick(GridView view, Point pt) {
GridHitInfo info = view.CalcHitInfo(pt);
if(info.InRow || info.InRowCell) {
string colCaption = info.Column == null ? "N/A" : info.Column.GetCaption();
MessageBox.Show(string.Format("DoubleClick on row: {0}, column: {1}.", info.RowHandle, colCaption));
}
}
http://www.devexpress.com/Support/Center/Question/Details/A2934
Let's say you have two gridviews (I'm guessing you're using gridviews in your grid control): gvMaster and gvDetail.
You should implement event DoubleClick for your gvDetail in order to achieve desired functionality:
private void gvDetail_DoubleClick(object sender, EventArgs e) {
var gv = sender as GridView; // sender is not gvDetail! It's an instance of it. You have as many as there are rows in gvMaster
var row = gv.GetDataRow(e.FocusedRowHandle); // or use gv.GetRow(e.FocusedRowHandle) if your datasource isn't DataSet/DataTable (anything with DataRows in it)
MessageBox.Show(row["Kalip"].ToString());
}

RowState property not changing

I have an table edit that won't save changes. It looks like the problem is that the RowState is not changing. The foreach loop is for debugging:
private void btnSave_Click(object sender, EventArgs e)
{
this.Validate();
bs.EndEdit();
dsEdit.Tables["broker"].GetChanges();
DataTable dtOut = dsEdit.Tables["broker"];
foreach (DataRow rOut in dtOut.Rows)
{
Console.WriteLine(rOut.RowState.ToString());
Console.WriteLine(rOut["contactfax"]);
rOut["contactfax"] = "change";
Console.WriteLine(rOut.RowState.ToString());
Console.WriteLine(rOut["contactfax"]);
}
int n = sdaBkr.Update(dsEdit.Tables["broker"]);
MessageBox.Show(n.ToString() + " record(s) saved.");
}
The Console output is as follow::
Unchanged
fax number here
Unchanged
change
What can cause this? I don't see any unusual properties set in the database.
Answer found here: EndEdit on BindingSource updates DataTable, but rowstate still unchanged
Calling EndEdit on each row as
rOut.EndEdit();
fixes the problem, but I don't understand, and I don't see that in any documentation.

How to find matching words in Text Box and Datagrid when VirtualizingStackPanel.IsVirtualizing="true"?

I have Datagrid and Text Box in my Form. Datagrid is showing me existing items in my stock. I use Text Box to search and set focus to that row which is matching with my Text Box. Now it is working fine when VirtualizingStackPanel.IsVirtualizing="false" but it is very slow and getting a lot RAM resource.
Here is my code for this.
public IEnumerable<Microsoft.Windows.Controls.DataGridRow> GetDataGridRows(Microsoft.Windows.Controls.DataGrid grid)
{
var itemsSource = grid.ItemsSource as IEnumerable;
if (null == itemsSource) yield return null;
foreach (var item in itemsSource)
{
var row = grid.ItemContainerGenerator.ContainerFromItem(item) as Microsoft.Windows.Controls.DataGridRow;
if (null != row) yield return row;
}
}
private void SearchBoxDataGrid_TextChanged(object sender, TextChangedEventArgs e)
{
var row = GetDataGridRows(AssortDataGrid);
/// go through each row in the datagrid
foreach (Microsoft.Windows.Controls.DataGridRow r in row)
{
DataRowView rv = (DataRowView)r.Item;
// Get the state of what's in column 1 of the current row (in my case a string)
string t = rv.Row["Ассортимент"].ToString().ToLower();
if (t.StartsWith(SearchBoxDataGrid.Text.ToLower()))
{
AssortDataGrid.SelectedIndex = r.GetIndex();
AssortDataGrid.ScrollIntoView(AssortDataGrid.SelectedItem);
break;
}
}
}
What I want is to make it VirtualizingStackPanel.IsVirtualizing="true" but in this case my method is not working. I know why it is not working, my code will work only for showing part of Datagrid.
What do you recommend? How to fix this issue? Any idea will be appreciated. If you give any working code it will be fantastic. I hope I could explain my problem.
Virtualization means that WPF will reuse the UI components, and simply replace the DataContext behind the components.
For example, if your Grid has 1000 items and only 10 are visible, it will only render around 14 UI items (extra items for scroll buffer), and scrolling simply replaces the DataContext behind these UI items instead of creating new UI elements for every item. If you didn't use Virtualization, it would create all 1000 UI items.
For your Search to work with Virutalization, you need to loop through the DataContext (DataGrid.Items) instead of through the UI components. This can either be done in the code-behind, or if you're using MVVM you can handle the SeachCommand in your ViewModel.
I did a little coding and make it work. If anyone needs it in future please, use it.
Firstly I am creating List of Products
List<string> ProductList;
Then on Load Method I list all my products to my Product List.
SqlCommand commProc2 = new SqlCommand("SELECT dbo.fGetProductNameFromId(ProductID) as ProductName from Assortment order by ProductName desc", MainWindow.conn);
string str2;
SqlDataReader dr2 = commProc2.ExecuteReader();
ProductList = new List<string>();
try
{
if (dr2.HasRows)
{
while (dr2.Read())
{
str2 = (string)dr2["ProductName"];
ProductList.Insert(0, str2.ToLower ());
}
}
}
catch (Exception ex)
{
MessageBox.Show("An error occured while trying to fetch data\n" + ex.Message);
}
dr2.Close();
dr2.Dispose();
After that I did some changes in SearchBoxDataGrid_TextChanged
private void SearchBoxDataGrid_TextChanged(object sender, TextChangedEventArgs e)
{
int pos = 0;
string typedString = SearchBoxDataGrid.Text.ToLower();
foreach (string item in ProductList)
{
if (!string.IsNullOrEmpty(SearchBoxDataGrid.Text))
{
if (item.StartsWith(typedString))
{
pos = ProductList.IndexOf(item);
AssortDataGrid.SelectedIndex = pos;
AssortDataGrid.ScrollIntoView(AssortDataGrid.SelectedItem);
break;
}
}
}
}
Now it works when VirtualizingStackPanel.IsVirtualizing="true".
That is all.

Resources