public static void ShowNoResultFoundGridWiew<T>(List<T> source, GridView gv, string text) where T : new()
{
if (source == null)
return;
source.Add(new T());
gv.DataSource = source;
gv.DataBind();
// Get the total number of columns in the GridView to know what the Column Span should be
int columnsCount = gv.Columns.Count;
gv.Rows[0].Cells.Clear(); // clear all the cells in the row
gv.Rows[0].Cells.Add(new TableCell()); //add a new blank cell
gv.Rows[0].Cells[0].ColumnSpan = columnsCount; //set the column span to the new added cell
// You can set the styles here
////gv.Rows[0].Cells[0].HorizontalAlign = HorizontalAlign.Center;
////gv.Rows[0].Cells[0].ForeColor = System.Drawing.Color.Red;
////gv.Rows[0].Cells[0].Font.Bold = true;
// Or you can pass a css class name
//gv.Rows[0].Cells[0].CssClass = "EmptyDataRowStyle";
gv.Rows[0].Cells[0].Text = text;
}
How can i create in the sam way empty row for repeater? Is it possible. I do not know how to add row and clear it...
Repeaters aren't guaranteed to contain rows and columns: they can have any internal structure (or no structure), so you can't do the same thing.
You're probably better off hiding the repeater and showing an entirely different control when your data source has no items, like an HTML literal.
Related
I have a method as such :
public void setResults(Documents[] doc)
{
//I call a method to set the columns
setColumns(doc[0].getColumnsToDisplay())
//Here i populate the DataGrid
foreach (Documents element in doc)
{
/dt is a datatable
DataRow dr = dt.NewRow();
foreach (string col in results[0].getColumnsToDisplay())
{
object val;
(element.getAttributes() as IDictionary<string, object>).TryGetValue(col, out val);
dr[col] = val.ToString();
}
dt.Rows.Add(dr);
}
gridSearchResults.DataSource = dt;
}
Is there a way to store "doc" reference on each row ? so that if i select a row, i can be able to return the "doc" object ? Looking for some kind of Tag property alternative for rows or something different.
When you want to show a list of your objects in a DataGridView, you don't need to use a DataTable. You can simply set your list as DataSource of your DataGridView:
public void setResults(Documents[] doc)
{
gridSearchResults.DataSource = doc;
}
Then if you want to know the object behind the row, you can simply use DataBoundItem property of the DataGridViewRow and cast it to your object type:
var documents= (Documents)gridSearchResults.Rows[0].DataBoundItem;
For more information and samples, you can see:
How to: Access Objects Bound to Windows Forms DataGridView Rows.
If you want to show only some columns in the DataGridView, add the columns you need this way:
this.dataGridView1.Columns.Clear();
this.dataGridView1.AutoGenerateColumns = false;
//Create Column
var column1 = new DataGridViewTextBoxColumn()
{
Name = "firstNameColumn", /*Name of Column*/
HeaderText = "First Name", /*Title of Column*/
DataPropertyName = "FirstName" /*Name of the property to bind to cilumn*/
};
//Add column to grid
this.dataGridView1.Columns.Add(column1);
You should use DataGridView instead of DataGrid. I assume you're trying to get the object after postback.
//DO NECESSARY NULL CHECKS!!!
DataRow row = (gridSearchResults.SelectedRows[0].DataBoundItem as DataRowView).Row;
Documents selected = (Documents)row;
I have data gridview and in one colum contain numeric values and i am trying to apply filters like show greater and etc but I am not able to come with solution.
screen:
code:
calling the class method and assigning the value to datagridview
dataGridViewKeywords = filter.Filter(dataGridViewKeywords, mainValue, true);
Class File:
class FilterDataGridView
{
private DataGridView modifiedDGV = new DataGridView();
private string keyword;
private int competionScore;
DataTable dt = new DataTable();
public DataGridView Filter (DataGridView dgv, int value, bool isabove)
{
modifiedDGV.Columns.Add("keyword", "Keyword") ;
modifiedDGV.Columns.Add("competition", "Avg. Competition Score");
modifiedDGV.Columns.Add("moreinfo", "More Info");
if (isabove)
{
for (int row = 0; row < dgv.Rows.Count; row++)
{
competionScore = Convert.ToInt32(dgv.Rows[row].Cells[1].Value);
keyword = dgv.Rows[row].Cells[0].Value.ToString();
if (competionScore > value)
modifiedDGV.Rows.Add(keyword, competionScore, "View");
}
}
return modifiedDGV;
}
The cleanest solution is to work with BindingSource.
You provide your data within a BindingSource-class and set the DataGridView.DataSource to this BindingSource.
BindingSource itself is more or less a better List and also has a Filter-property which lets you apply the criteria very easy. This way you don't have to mess around with all these items and even create a second DataGridView.
I'm attempting to automate a data processing task for files of various formats and fields. I've created a program that determines the delimiter of a delimited file, and loads a chunk of the file into a DataGridView on a form, so that the user can confirm some fields of the file before the file is bulk loaded into a SQL table. The table will be created on the fly, using some of the field names the user has selected in a combobox in the datagrid.
That's my goal, but I'm not sure I'm approaching the problem correctly.
At this point, I've created a BindingSource for the comboboxes ...
BindingSource bindingSource = new BindingSource();
Here I show the DataGridView of the selected file, adding a column for each field in the data file
private void ShowDataGridView(string file, string delimiter, string[] fieldNames, string[] fieldLengths)
{
StreamReader fileReader = new StreamReader(file);
if (bindingSource.Count == 0)
{
bindingSource.Add("FIRSTNAME");
bindingSource.Add("LASTNAME");
bindingSource.Add("ADDRESS1");
bindingSource.Add("ADDRESS2");
bindingSource.Add("CITY");
bindingSource.Add("STATE");
bindingSource.Add("ZIP");
bindingSource.Add("COMPANY");
bindingSource.Add("EMAIL");
bindingSource.Add("");
}
dataGridView1.Rows.Clear();
dataGridView1.Columns.Clear();
int count = 0;
for (int i = 0; i < 17; i++) //read 17 lines into datagridview for field confirmation, 17 lines just so happens to fill my datagridview nicely, last row will be combobox for field name selection
{
string[] fields = StringFunctions.Split(fileReader.ReadLine(), delimiter, Convert.ToString("\""));
count = fields.Count();
if (i == 0)
{
// Adding Column Header to DataGridView
for (int x = 0; x < count; x++)
{
DataGridViewTextBoxColumn columnDataGridTextBox = new DataGridViewTextBoxColumn();
columnDataGridTextBox.Name = fieldNames[x];
columnDataGridTextBox.HeaderText = fieldNames[x];
dataGridView1.Columns.Add(columnDataGridTextBox);
}
}
dataGridView1.Rows.Add(fields);
}
for (int x = 0; x < count; x++)
{
DataGridViewComboBoxCell combobox = new DataGridViewComboBoxCell();
combobox.DataSource = bindingSource;
dataGridView1[x, 16] = combobox; //remember 17 rows added, combobox will be last row in datagridview
combobox = null;
}
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
fileReader.Close();
fileReader = null;
}
Okay, so now I have a view of the data, and comboboxes for all fields of the data. Certain fields are mandatory, (the BindingSource field names) I want the user to be able to select the appropriate field name for the column of data from the combobox. When the user has selected a field from the combobox, I want to remove that field name from the BindingSource, so user can't select same field name for another column. The remaining fields will have default field names eg (FirstName,Field2,LastName,Address1, Field5, Field6,Address2 etc)
Combobox is where I'm having problems :)
I've searched for code snippets and I'm making some progress, but I could use some advice from someone who has a better grasp of datagridview events and how to handle them. I don't really know what I'm doing, just flinging stuff on the wall to see if it sticks. The following is what I've tried so far ...
InitializeComponent();
dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(DataGridViewEditingControlShowing);
private void DataGridViewEditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
//here we will add the combo box's selected event changed
ComboBox cmbBox;
if (dataGridView1.CurrentCell is DataGridViewComboBoxCell)
{
cmbBox = e.Control as ComboBox;
if (cmbBox == null)
return;
cmbBox.SelectedIndexChanged += cmbBox_SelectedIndexChanged;
}
}
//This will display value of Select values of Combo Box
//which is DataGridView
void cmbBox_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox cmbBox = (ComboBox)sender;
if (cmbBox.SelectedValue != null)
{
MessageBox.Show(cmbBox.SelectedValue.ToString()); //testing
bindingSource.Remove(cmbBox.SelectedValue); //this removes it from the current combobox as well, no good. Also run time error when clicking into a different combobox
}
}
I hope I've been descriptive enough and posted enough code to give any possible code guru helpers a feel for what I'm trying to accomplish. If more information is needed, please let me know. Any ideas/solutions are greatly appreciated.
Thanks!
You're on the right track, but for this to work I think each combobox will need its own datasource, so they can be manipulated individually. If they all share the same source, they can't have different contents, which is what you want (selecting X from combobox A should remove that from all other comboboxes.)
In your loop where you create the comboboxes, "clone" the datasource so they each have their own.
I need to get the total number of cells that are present in a datagridview. This is then used to determine if I want to include the column header text when copying/pasting the data, I only want this displayed if all records are selected.
I am using the following code to get the total number of cells but is there a better way to get this value?
var totalCellCount = DataGridView2.ColumnCount * DataGridView2.RowCount;
I couldn't find a property that contained a count of all cells, maybe I am missing it. Is there a better way to get the number of cells?
My datagridview has the ClipboardCopyMode set to EnableWithAutoHeaderText, but I want to set it to EnableAlwaysIncludeHeaderText when they select all rows/columns in the grid. So I am using the total number of cells in the code below:
private void DataGridView_KeyPress(object sender, KeyPressEventArgs e)
{
if (m_RecordCount == 0)
return;
var totalCellCount = DataGridView2.ColumnCount * DataGridView2.RowCount;
if (DataGridView2.SelectedCells.Count == totalCellCount)
{
if (e.KeyChar == (char)3)
{
DataGridView2.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
var clipboardContent = this.DataGridView2.GetClipboardContent();
if (clipboardContent != null)
{
Clipboard.SetText(clipboardContent.GetText(TextDataFormat.Text));
}
e.Handled = true;
}
}
}
The DataGrid.Items property returns a DataGridItemCollection representing the DataGridItems in the DataGrid.
Each DataGridItem is representative of a single row in the rendered table. Also, the DataGridItem exposes a Cells property which represents the no. of tablecells (in other words, the columns) in the rendered table. From here if you need any other custom scenarios you will have to either add it to the original Question or code a solution
var rowCount = DataGridView2.Items.Count; //Number of Items...i.e. Rows;
// Get the no. of columns in the first row.
var colCount = DataGridView2.Items[0].Cells.Count;
if you want the total number of Rows also try
If you want to get at total items an you want a real total for example if you have multiple pages.. If so you shouldn't be trying to find that information from the GridView but instead look at the underlying DataSource that you bound your GridView.
Example ----
List<SomeObject> lis = GetYourData();
DataGrid.DataSource = list;
DataGrid.DataBind();
// if you want to get the count for a specific page
int currentPage = 2;
int countForPage2 = (list.Count > currentPage * totalItemsPerPage)) ?
totalItemsPerPage : list.Count - ((currentPage - 1) * totalItemsPerPage);
I am working with a gridview that pulls data from a SQL database based on selections in dropdown lists. The source table has six columns for attributes of the selection, but depending on what is chosen, there could be anywhere from one to six of those that are empty (all null values). When the column is empty, I would like to have it hidden so the page is less clunky and confusing.
I've searched around for an answer for the past couple days, but what I have found so far is either related to hiding columns that you know are empty which I will not know or removing them in the SQL code which I think doesn't work if the column is called for in the gridview code and doesn't exist in the query.
I'm very new to ASP.NET, so I'm sorry if some of my terminology is off! Let me know if you have any questions about what I'm asking.
Thanks in advance for your help!
Instead of hiding empty columns, why don't you add the columns you want in code behind?
When you retrieve the data to be displayed, you know which columns are present. You can add them and databind them in code behind.
To get you started with this, here is some code from a helpful article on how to do this:
BoundField nameColumn = new BoundField();
nameColumn.DataField = "Name";
nameColumn.HeaderText = "Person Name";
GridView1.Columns.Add(nameColumn);
You could try:
Set up the gridview will all columns hidden (Visible="false")
In the gridview's RowDataBound event, check each of the column values and if it has data, set the column to show (Visible="true")
The RowDataBound method could look something like this:
void YourGridview_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// if this is a SqlDataSource you can use DataRowView,
// otherwise use whatever type is used in the data source
DataRowView rowView = (DataRowView)e.Row.DataItem;
if (!String.IsNullOrEmpty(rowView["ColumnA"]))
YourGridview.Columns[0].Visible = true;
// repeat for your other columns
}
}
Best way to do that for web:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
namespace MyProject
{
public static class ExtensionGridView
{
public static GridView RemoveEmptyColumns(this GridView gv)
{
// Make sure there are at least header row
if (gv.HeaderRow != null)
{
int columnIndex = 0;
// For each column
foreach (DataControlFieldCell clm in gv.HeaderRow.Cells)
{
bool notAvailable = true;
// For each row
foreach (GridViewRow row in gv.Rows)
{
string columnData = row.Cells[columnIndex].Text;
if (!(string.IsNullOrEmpty(columnData) || columnData ==" "))
{
notAvailable = false;
break;
}
}
if (notAvailable)
{
// Hide the target header cell
gv.HeaderRow.Cells[columnIndex].Visible = false;
// Hide the target cell of each row
foreach (GridViewRow row in gv.Rows)
row.Cells[columnIndex].Visible = false;
}
columnIndex++;
}
}
return gv;
}
}
}
Instead of this code:
if (!String.IsNullOrEmpty(rowView["ColumnA"]))
YourGridview.Columns[0].Visible = true;
Use this one:
if (!String.IsNullOrEmpty(Convert.Tostring(rowView["ColumnA"])) )
YourGridview.Columns[0].Visible = true;
on the onItemBound event of the grid, you can check the value of the variable to be set in the column cell and set its visibility accordingly