I am using C1FlexGrid on windows forms.
I have SELECT column in the grid which of type Checkbox.
I have an edit button outside the grid on the form.
Initially I want the Select column in the grid to be disabled.
Upon clicking Edit Button, I want the Select column to be enabled (so that it can be ticked for each row)
Once I press save, I want to disable Select Column again.
Any idea ?
I am assuming that you have used CheckBoxes in a C1lexGrid column by changing the columns datatype to boolean. It is very easy to stop the user from interacting with a particular column in C1FlexGrid. Refer the following snippet:
C#
// Assuming the checkboxes are in column 1
private void Save_Click(object sender, EventArgs e)
{
//...
// Save the flexgrid..
//...
// disable the column
this.c1FlexGrid1.Cols[1].AllowEditing = false;
this.c1FlexGrid1.Cols[1].AllowDragging = false;
this.c1FlexGrid1.Cols[1].AllowFiltering = C1.Win.C1FlexGrid.AllowFiltering.None;
this.c1FlexGrid1.Cols[1].AllowSorting = false;
}
private void Edit_Click(object sender, EventArgs e)
{
this.c1FlexGrid1.Cols[1].AllowEditing = true;
this.c1FlexGrid1.Cols[1].AllowDragging = true;
this.c1FlexGrid1.Cols[1].AllowFiltering = C1.Win.C1FlexGrid.AllowFiltering.None;
this.c1FlexGrid1.Cols[1].AllowSorting = true;
}
VB
'Assuming the checkboxes are in column 1
Private Sub Save_Click(sender As Object, e As EventArgs) Handles Save.Click
'...
' Save the flexgrid..
'...
' disable the column
Me.c1FlexGrid1.Cols(1).AllowEditing = False
Me.c1FlexGrid1.Cols(1).AllowDragging = False
Me.c1FlexGrid1.Cols(1).AllowFiltering = C1.Win.C1FlexGrid.AllowFiltering.None
Me.c1FlexGrid1.Cols(1).AllowSorting = False
End Sub
Private Sub Edit_Click(sender As Object, e As EventArgs) Handles Edit.Click
Me.c1FlexGrid1.Cols(1).AllowEditing = True
Me.c1FlexGrid1.Cols(1).AllowDragging = True
Me.c1FlexGrid1.Cols(1).AllowFiltering = C1.Win.C1FlexGrid.AllowFiltering.None
Me.c1FlexGrid1.Cols(1).AllowSorting = True
End Sub
Related
There is an example of the dynamic cell styling for jXLS 1.x, but I can not find anything closer than this example for AreaListener.
I have a very basic template for the XLS generation, and the processing code as simple as
context.putVar("headers", columns);
context.putVar("data", cells);
context.getConfig().setCellStyleMap();
JxlsHelper.getInstance().processTemplate(is, result, context);
How can I add some listener that will allow me to modify the style for certain cells (like add the word-wrap for the text longer than N character, or change the background color if the value is of certain pattern)?
You can achieve it like this
In the main method:
try(InputStream is = HighlightDemo.class.getResourceAsStream("highlight_template.xls")) {
try (OutputStream os = new FileOutputStream("target/highlight_output.xls")) {
PoiTransformer transformer = PoiTransformer.createTransformer(is, os);
AreaBuilder areaBuilder = new XlsCommentAreaBuilder(transformer, false);
List<Area> xlsAreaList = areaBuilder.build();
Area mainArea = xlsAreaList.get(0);
Area loopArea = xlsAreaList.get(0).getCommandDataList().get(0).getCommand().getAreaList().get(0);
loopArea.addAreaListener(new HighlightCellAreaListener(transformer));
Context context = new Context();
context.putVar("employees", employees);
mainArea.applyAt(new CellRef("Result!A1"), context);
mainArea.processFormulas();
transformer.write();
}
}
The template used in this example is the same as in Object Collection Demo sample. The trickiest part is to find the area where do you want to apply the AreaListener. In this case I just traversed from the root area to the EachCommand area where I wish to highlight employees with payment over 2000.
The AreaListener implementation is similar to the one in AreaListener example
public class HighlightCellAreaListener implements AreaListener {
private final CellRef paymentCell = new CellRef("Template!C4")
...
public void afterTransformCell(CellRef srcCell, CellRef targetCell, Context context) {
System.out.println("Source: " + srcCell.getCellName() + ", Target: " + targetCell.getCellName());
if(paymentCell.equals(srcCell)){ // we are at employee payment cell
Employee employee = (Employee) context.getVar("employee");
if( employee.getPayment().doubleValue() > 2000 ){ // highlight payment when >= $2000
logger.info("highlighting payment for employee " + employee.getName());
highlightCell(targetCell);
}
}
}
private void highlightCell(CellRef cellRef) {
Workbook workbook = transformer.getWorkbook();
Sheet sheet = workbook.getSheet(cellRef.getSheetName());
Cell cell = sheet.getRow(cellRef.getRow()).getCell(cellRef.getCol());
CellStyle cellStyle = cell.getCellStyle();
CellStyle newCellStyle = workbook.createCellStyle();
newCellStyle.setDataFormat( cellStyle.getDataFormat() );
newCellStyle.setFont( workbook.getFontAt( cellStyle.getFontIndex() ));
newCellStyle.setFillBackgroundColor( cellStyle.getFillBackgroundColor());
newCellStyle.setFillForegroundColor(IndexedColors.ORANGE.getIndex());
newCellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
cell.setCellStyle(newCellStyle);
}
I am trying to solve this good old problem in my own environment, adapted lots of different solutions, still no success.
I have a User Control, named EntryGrid, that has a DataGridView, it's headers and such things are set in the code. Then there is a form that has an EntryGrid dropped to it.
I know that excel columns must be prepared to be able to paste all cells into a row, for this I used this solution: copypaste, except the Copy part. This is how it looks like at my place:
Private Sub EntryGrid_KeyDown(sender As Object, e As KeyEventArgs) Handles EntryGrid4.KeyDown, EntryGrid8.KeyDown, EntryGrid16.KeyDown, EntryGrid32.KeyDown
e.Handled = True
Dim entryGrid As EntryGrid = sender
Dim dataGrid As DataGridView = entryGrid.DataGrid
If (e.Control And e.KeyCode = Keys.V) Then
MessageBox.Show("Success") 'for now
End If
End Sub
This is absolutely not working for me. I even set KeyPreview to True in the form, but nothing happens ever.
Then I tried this solution, mine with any result:
Private Sub EntryGrid_EditingControlShowing(sender As System.Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles EntryGrid4.EditingControlShowing
AddHandler e.Control.KeyDown, AddressOf cell_KeyDown
End Sub
Private Sub cell_KeyDown(sender As Object, e As KeyEventArgs)
If e.KeyCode = Keys.V Then
MessageBox.Show("Success")
End If
End Sub
EntryGrid4 is the name of the usercontrol on the form, but it hasn't got any EditingControlShowing event, only DataGridView has, but I cannot use like this: EntryGrid4.DataGrid.EditingControlShowing
I created an event in EntryGrid (Public Event EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs)), but anything's changed.
I am able to paste anything from clipboard to a cell, but it had been possible before I started the modifying.
Thanks for any idea!
ProcessCmdKey method of your UserControl is what you are looking for. Override it and check for Ctrl + V and do what you need. For example:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.V))
{
if (dataGridView1.EditingControl != null)
dataGridView1.EditingControl.Text = Clipboard.GetText();
else if (dataGridView1.CurrentCell != null)
this.dataGridView1.CurrentCell.Value = Clipboard.GetText();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I import a csv file into a datatable which, unfortunately, put my datas into string columns even those with figures.
So I have to convert the format of some columns (unless there is an other way) into datetime, integer or double why I wrote the following code :
Public Sub ChangeFieldType(ByRef dataTable As DataTable, ByVal fieldIndex As Integer, ByVal newType As Type)
Dim newDataTable As DataTable = dataTable.Clone
newDataTable.Columns(fieldIndex).DataType = newType
For Each row As DataRow In dataTable.Rows
newDataTable.ImportRow(row)
Next
dataTable = newDataTable
End Sub
But there are some empty cells which in string format is vbnullstring. My question is is there an easier way then my code and if not is there an faster way than converting the empty cells then that way :
Public Sub ChangeFieldType(ByRef dataTable As DataTable, ByVal fieldIndex As Integer, ByVal newType As Type)
Dim newDataTable As DataTable = dataTable.Clone
newDataTable.Columns(fieldIndex).DataType = newType
For Each row As DataRow In dataTable.Rows
If row(fieldIndex) = vbNullString Then
row(fieldIndex) = Nothing
End If
newDataTable.ImportRow(row)
Next
dataTable = newDataTable
End Sub
Because this is very very slow.
Thanks
When importing the csv file if you already know the column types beforehand then you should make a table with those columns and then fill the data. Cloning a table and then filling the data again is very slow process especially if data is large
You can refer to the following
http://social.msdn.microsoft.com/Forums/windows/en-US/34b6a1e8-5103-42a3-aa45-cdc0cea461f2/importing-csv-file-to-datatable-problem-with-converting-data-type
Use the below Code To Convert The Data type of a Column in DataTable
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DataTable table = GetTable();
DataColumn dc = new DataColumn("MyDate", Type.GetType("System.String"));
table.Columns.Add(dc);
foreach (DataRow row in table.Rows)
{
row["MyDate"] =Convert.ToDateTime(row["Date"].ToString()).ToString("dd-MM-yyyy");
}
GridView1.DataSource = table;
GridView1.DataBind();
}
static DataTable GetTable()
{
// Here we create a DataTable with four columns.
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("SortName", typeof(string));
table.Columns.Add("FullName", typeof(string));
table.Columns.Add("Date", typeof(DateTime));
// Here we add five DataRows.
table.Rows.Add(25, "Geli", "Smruti", DateTime.Now.AddDays(1).ToString("yyyy-MM-dd"));
table.Rows.Add(50, "Gelu", "Ramesh", DateTime.Now.AddDays(2).ToString("yyyy-MM-dd"));
table.Rows.Add(10, "Nitu", "Mama", DateTime.Now.AddDays(3).ToString("yyyy-MM-dd"));
table.Rows.Add(21, "Babu", "Gelu", DateTime.Now.AddDays(4).ToString("yyyy-MM-dd"));
return table;
}
}
Add a Column To Existing DataTable & Update the Data to The new Column Which you Want to Change the DataType.
I want to delete row from datagridview when user clicks the delete button.The datagridview bounded to datatable _dt so i remove the row from _dt and try to rebind the modified _dt to datagridview but instead of deleting the row gets added to the last row of the datagridview what am I doing wrong here
private void btnDelete_Click(object sender, EventArgs e)
{
if (dataGridView1 != null && dataGridView1.SelectedRows.Count == 1)
{
string key = dataGridView1.SelectedRows[0].Cells["ID"].Value.ToString();
DataColumn[] keyColumns = new DataColumn[1];
keyColumns[0] = _dt.Columns["ID"];
_dt.PrimaryKey = keyColumns;
rowToDelete = _dt.Rows.Find(key);
_dt.Rows.Remove(rowToDelete);
_dt.AcceptChanges();
SqlCommandBuilder cb = new SqlCommandBuilder(_sqlDa);
_sqlDa.Fill(_dt);
_sqlDa.Update(_dt);
dataGridView1.DataSource = null;
dataGridView1.DataSource = _dt;
}
}
No need for Fill before update and also delete this row
_dt.AcceptChanges();
because this will remove the row from memory and when you call update
only the remaining rows are updated, it will not delete the row from database.
No need to call Fill Before Update, because Fill will get data again from db and your changes will be lost. So This will work for you.
SqlCommandBuilder cb = new SqlCommandBuilder(_sqlDa);
//_sqlDa.Fill(_dt);
_sqlDa.Update(_dt);
I am having problems selecting a row out of the DataGridView on a search. The data source is a DataTable from a database. I am using a search box that checks the DataGridView for a product matching the product key, and i want to select it if found.
Here is what i have:
private void search_btn_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in products_dgv.Rows)
{
string tempCode = row.Cells[0].Value.ToString(); //Code comparing
if (tempCode == code_tb.Text) //Checks if code matchs the search code
{
//I would like to do a products_dgv.selectedIndex = row.Index but it
//doesnt work
break;
}
}
}
Any help is much appreciated. Thank You!
You can use the CurrentCell property of the DataGridView to set the selection. If you are using FullRowSelect as selection mode, just use any cells in the row that you would like to select.
For example:
...
if (tempCode == code_tb.Text) //Checks if code matchs the search code
{
products_dgv.CurrentCell = row.Cells[0];
break;
}
...