H guys, I am using VS2005 C# and SQL Server 2005.
I have a search for my GridView and I would like to use the Sort function of the GridView to sort my search results.
However, after every time I have my results filtered, when I press the header to sort my DataGrid, it always reset my GridView back to the original full data from the table.
E.g.
a) My webpage loads, a gridview containing data of 58 students.
b) I search for James under Names and 18 results are displayed in the GridView.
c) I press on the header Class to sort results by class.
d) The GridView refreshes and goes back to original full list of 58 students.
I tried:
Implementing the search table on a seperate webpage so it would not collide with the original gridview.
Changing the gridview name to another name.
I realize that:
When I hover my pointer above the header, it will always display
javascript:_doPostBack('ctl00$MainContent$GridView1,Sort$Issue),
even though I may have changed my GridView1 to another name
I need some solution in sorting search results in gridview, instead of bringing the original data back when I sort them.
I have implemented that using the ViewState to store the sort direction, either ASC or DESC in the following way:
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
listBindByName(); //this would be your procedure to look for the data you want
DataSet dsSortTable = GridView1.DataSource as DataSet;
DataTable dtSortTable = dsSortTable.Tables[0];
if (dtSortTable != null)
{
DataView dvSortedView = new DataView(dtSortTable);
dvSortedView.Sort = e.SortExpression + " " + getSortDirectionString();
ViewState["sortExpression"] = e.SortExpression;
GridView1.DataSource = dvSortedView;
GridView1.DataBind();
}
UpdatePanel1.Update();
}
private string getSortDirectionString()
{
if (ViewState["sortDirection"] == null)
{
ViewState["sortDirection"] = "ASC";
}
else
{
if (ViewState["sortDirection"].ToString() == "ASC")
{
ViewState["sortDirection"] = "DESC";
return ViewState["sortDirection"].ToString();
}
if (ViewState["sortDirection"].ToString() == "DESC")
{
ViewState["sortDirection"] = "ASC";
return ViewState["sortDirection"].ToString();
}
}
return ViewState["sortDirection"].ToString();
}
Let me know if any doubt.
suppose when you call gridview for Bind in Page load
protected void Page_Load(object sender, EventArgs e)
{
fillgrid(false, string.Empty, false); //
}
public void fillgrid(bool sorting, string sortexpression, bool sortdir)
{
//binding codes
var data = from item in DBcontent.Tablename
select new
{
Title = item.Title
}
if (sorting)
{
if (sortexpression == "Title")
{
if (sortdir)
{
GrieviewID.DataSource = data.OrderBy(id => id.Title).ToList();
}
else
{
GrieviewID.DataSource = data.OrderByDescending(id => id.Title).ToList();
}
}
else
{
GrdID.DataSource = data.OrderByDescending(id => id.StartDate).ToList();
}
GrdID.DataBind();
}
protected void grdevents_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
grdevents.PageIndex = e.NewPageIndex;
BindAndSortGrid();
}
/// <summary>
/// Gets the sort direction.
/// </summary>
/// <param name="column">The column.</param>
/// <returns></returns>
private string GetSortDirection(string column)
{
// By default, set the sort direction to ascending.
string sortDirection = "ASC";
// Retrieve the last column that was sorted.
string sortExpression = ViewState["SortExpression"] as string;
if (sortExpression != null)
{
// Check if the same column is being sorted.
// Otherwise, the default value can be returned.
if (sortExpression == column)
{
string lastDirection = ViewState["SortDirection"] as string;
if ((lastDirection != null) && (lastDirection == "ASC"))
{
sortDirection = "DESC";
}
}
}
// Save new values in ViewState.
ViewState["SortDirection"] = sortDirection;
ViewState["SortExpression"] = column;
return sortDirection;
}
/// <summary>
/// Bind and sort grid.
/// </summary>
private void BindAndSortGrid()
{
bool sortdir;
if (ViewState["SortDirection"] != null && ViewState["SortExpression"] != null)
{
sortdir = ViewState["SortDirection"].ToString() == "ASC" ? true : false;
fillgrid(true, ViewState["SortExpression"].ToString(), sortdir);
}
else
fillgrid(false, string.Empty, false);
}
protected void grdevents_Sorting(object sender, GridViewSortEventArgs e)
{
bool sortdir = GetSortDirection(e.SortExpression) == "ASC" ? true : false;
fillgrid(true, e.SortExpression.ToString(), sortdir);
}
Follow below code...Hopes its help
Related
I need edit the row of GridView in RowDataBound event.
If tried edit one row with field Area not null value I don't have problem, but if tried edit one row with field Area null or empty value I have the classic error :
Object reference not set to an instance of an object
On the line :
ddlCities.Items.FindByValue(hdnval.Value).Selected = true;
I think that inserted in my code this condition resolve the problem but without success :
if (!string.IsNullOrEmpty(hdnval.Value))
{
ddlCities.Items.FindByValue(hdnval.Value).Selected = true;
}
else
{
ddlCities.Items.FindByValue(hdnval.Value).Selected = false;
}
Please help me, thank you in advance.
My code below.
protected void gvProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && gvProducts.EditIndex == e.Row.RowIndex)
{
DropDownList ddlCities = (DropDownList)e.Row.FindControl("Area");
HiddenField hdnval = (HiddenField)e.Row.FindControl("hdnArea");
string query = " Select distinct Area from ... ; ";
OdbcCommand cmd = new OdbcCommand(query);
ddlCities.DataSource = GetData(cmd);
ddlCities.DataTextField = "Area";
ddlCities.DataValueField = "Area";
ddlCities.DataBind();
if (!string.IsNullOrEmpty(hdnval.Value))
{
ddlCities.Items.FindByValue(hdnval.Value).Selected = true;
}
else
{
ddlCities.Items.FindByValue(hdnval.Value).Selected = false;
}
}
}
Please try :
if(ddlCities.Items.FindByValue(hdnval.Value) != null)
{
ddlCities.Items.FindByValue(hdnval.Value).Selected = true;
}
I hope I have helped you.
There is datagridview in a form that shows content of table of database, one column of table type is boolean, so in datagridview shows true/false, but i want to customize it to show Yes/No.
which way you suggest?
When it comes to custom formatting, two possible solutions comes in my mind.
1.Handle CellFormatting event and format your own.
void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == yourcolumnIndex)
{
if (e.Value is bool)
{
bool value = (bool)e.Value;
e.Value = (value) ? "Yes" : "No";
e.FormattingApplied = true;
}
}
}
2.Use Custom Formatter
public class BoolFormatter : ICustomFormatter, IFormatProvider
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
{
return this;
}
return null;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (arg == null)
{
return string.Empty;
}
bool value = (bool)arg;
switch (format ?? string.Empty)
{
case "YesNo":
{
return (value) ? "Yes" : "No";
}
case "OnOff":
{
return (value) ? "On" : "Off";
}
default:
{
return value.ToString();//true/false
}
}
}
}
Then use it like this, and handle CellFormatting event to make it work
dataGridView1.Columns[1].DefaultCellStyle.FormatProvider = new BoolFormatter();
dataGridView1.Columns[1].DefaultCellStyle.Format = "YesNo";
void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.CellStyle.FormatProvider is ICustomFormatter)
{
e.Value = (e.CellStyle.FormatProvider.GetFormat(typeof(ICustomFormatter)) as ICustomFormatter).Format(e.CellStyle.Format, e.Value, e.CellStyle.FormatProvider);
e.FormattingApplied = true;
}
}
Edit
You can subscribe to CellFormatting event like this
dataGridView1.CellFormatting += dataGridView1_CellFormatting;
Hope this helps
void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
var grid = (DataGridView)sender;
if (grid.Columns[e.ColumnIndex].Name == "IsActive")
{
e.Value = (bool)e.Value ? "True_Text_Replace" : "False_Text_Replace";
e.FormattingApplied = true;
}
}
How about this if you only want to show.
It's easy to think.
private void Form1_Load(object sender, EventArgs e)
{
List<Person> list = new List<Person>();
list.Add(new Person(20, true));
list.Add(new Person(25, false));
list.Add(new Person(30, true));
dgv.DataSource = list;
//Hide checkbox column
dgv.Columns["IsProgrammer"].Visible = false;
//Add represent text column
DataGridViewTextBoxColumn textColumn = new DataGridViewTextBoxColumn();
textColumn.Name = "Yes / No";
dgv.Columns.Add(textColumn);
//true/false -> yes/no
foreach (var row in dgv.Rows.Cast<DataGridViewRow>())
row.Cells["Yes / No"].Value = (bool)row.Cells["IsProgrammer"].Value ? "Yes" : "No";
}
private class Person
{
public int Age { get; set; }
public bool IsProgrammer { get; set; }
public Person(int i, bool b)
{
Age = i;
IsProgrammer = b;
}
}
For vb code:
Use the code below to change boolean True/False display to Checkbox in Datagrid:
datagrid1.Columns.Add(New DataGridViewCheckBoxColumn)
Use the code below to display column header:
datagrid1.Columns(column number).HeaderText = "User Status"
If you swap the column out for a DataGridViewComboBoxColumn that is bound to a list/datatable having bool and string columns then it will decode the bool to whatever string you want (and the user can edit the values, but cannot put bad values in)
//your datatable has some boolean column and your DataGridView is bound to it
DataTable dt = new DataTable();
dt.Columns.Add("MyBoolColumn", typeof(bool)); //this is your bool column
dataGridView1.DataSource = dt;
//make a datatable that has 2 columns, string and bool, and 2 rows (one for true, one for false)
DataTable dv = new DataTable();
dv.Columns.Add("Dis"); //it will be shown in the combo
dv.Columns.Add("Val", typeof(bool)); //it will be used by the combo to set MyBoolColumn
dv.Rows.Add("Yeah baby", true);
dv.Rows.Add("Nooo way", false);
//make a combo box column bound to the values table above
//and connected to the table you show in the grid
var dgvcbc = new DataGridViewComboBoxColumn();
dgvcbc.DataPropertyName = "MyBoolColumn"; //connect to the grid table
dgvcbc.DisplayMember = "Disp"; //show this column
dgvcbc.ValueMember = "Val"; //use values from this
dgvcbc.DataSource = dv;
dataGridView1.Columns.Add(dgvcbc);
This grid will now show a combo where it once showed a checkbox, and editing the combo will change the boolean value
You don't have to bind the combo column to a datatable. Maybe you'd prefer a list of Tuple or ValueTuple as the backing data store for the Yes/No combo:
var dv2 = new List<Tuple<string, bool>>() {
new Tuple<string, bool>("Yeah baby", true),
new Tuple<string, bool>("Noooo way", false)
};
var dgvcbc2 = new DataGridViewComboBoxColumn();
dgvcbc2.DataPropertyName = "MyBoolColumn";
dgvcbc2.DisplayMember = "Item1"; //the string in the Tuple
dgvcbc2.ValueMember = "Item2"; //the bool in the Tuple
dgvcbc2.DataSource = dv2;
dataGridView1.Columns.Add(dgvcbc2);
If your datagridview is designed in the forms designer, the easiest thing would probably be to add a DispVal table to a strongly typed dataset, then it becomes available as a "project list instance" in the picker that lets you choose the datasource for the combo column
The answer where we handle CellFormatting event didn't work for me, though it seemed so simple and promising. Perhaps because I have bound a List as the DataSource to my DataGridView. I was getting the exception
value of the cell has a wrong type
I solved it in the DataSource List's class, so instead of having a bool property, I hid it and put the logic inside a string property, like this
Old
public bool PropertyName
{
get => someBusinessLogic();
}
New
[Browsable(false)] // will not be displayed in the DataGridView
public bool PropertyNameBool
{
get => someBusinessLogic();
}
public string PropertyName
{
get => this.PropertyNameBool ? "True" : "False";
}
This worked for me as this class is only used as a DataSource for my grid. But changing around the class may not work for everybody.
Populated list box like this:
if (ds != null)
{
ListPreviousRecords.Items.Clear();
ListPreviousRecords.DataSource = ds;
ListPreviousRecords.DataTextField = "Date";
ListPreviousRecords.DataValueField = "ID";
ListPreviousRecords.DataBind();
}
Get selected value:
protected void ListPreviousRecords_OnSelectedIndexChanged(object sender, EventArgs e)
{
if(ListPreviousRecords.SelectedItem.Value != "")
{
int mySelectedValue = int.Parse(ListPreviousRecords.SelectedItem.Value);// throwing null exception
loadPreviousDetails(mySelectedValue);
}
}
You can add this code in order to ensure that not null value is entered
if(!string.IsNullOrEmpty(ListPreviousRecords.SelectedItem.Value ))
{
...
}
And Ensure that AutoPostBack="true" is set on your control
link : http://msdn.microsoft.com/fr-fr/library/system.string.isnullorempty.aspx
Change:
if(ListPreviousRecords.SelectedItem.Value != "")
To:
if (!string.IsNullOrEmpty(ListPreviousRecords.SelectedItem))
Use ListPreviousRecords.SelectedValue.
if (!string.IsNullOrWhiteSpace(ListPreviousRecords.SelectedValue)) {
// ...
}
I have a Query that runs when the user submits a search and the gridview is loaded.
I want to page the gridview and would usually have my grid in a LoadGrid(). I have the paging working ok and everything is good until I want to view page 2 of the GridView.
protected void btn_Search_Click(object sender, EventArgs e)
{
// Init()
// -----
pnl_Message.Visible = false;
lbl_message.Text = String.Empty;
// Clear grid of previous results
// ==============================
ResultsGridView.DataSource = null;
ResultsGridView.DataBind();
try
{
using (var db = new dbDataContext())
{
// Check Fields
// ------------
if (txt_CustomerName.Text == string.Empty && txt_CCNo.Text == string.Empty &&
txt_SwiftNo.Text == string.Empty && drp_Provider.SelectedValue == string.Empty)
{
lbl_message.Text += "* Please enter a search term";
pnl_Message.Visible = true;
pnl_Message.CssClass = "loginError";
pnl_results.Visible = false;
}
// Search Database
// ---------------
if (lbl_message.Text == String.Empty)
{
var customer = txt_CustomerName.Text.Length > 1 ? txt_CustomerName.Text.Trim() :
"Xcxcx";
//var provider = drp_Provider.SelectedItem.Text.Trim();
var concern = txt_CCNo.Text == "" ? 0 : Convert.ToInt32(txt_CCNo.Text);
var swiftid = txt_SwiftNo.Text == "" ? 0 : Convert.ToInt32(txt_SwiftNo.Text);
// Check which fields populated
// ----------------------------
var result =
from c in db.tbl_Concerns
where (c.ProviderId == Convert.ToInt32(drp_Provider.SelectedValue))
|| (c.person_Fullname.Contains(customer))
|| (c.SwiftId == swiftid)
|| (c.ConcernId == concern)
select new
{
c.ConcernId,
Swift = c.SwiftId,
FullName = c.person_Fullname,
Provider = c.tbl_Provider.provider_Name,
Concern_Detail = c.tbl_RaisedConcern.RaisedConcernText,
DateFrom = c.concern_DateFrom,
DateTo = c.concern_DateTo
};
// If No Results
// -------------
if (!result.Any())
{
lbl_message.Text += "* No results match your search, please try again.";
pnl_Message.Visible = true;
pnl_Message.CssClass = "loginError";
}
else
{
// Show Table
// ----------
pnl_results.Visible = true;
ResultsGridView.DataSource = result;
ResultsGridView.DataBind();
// Table Header Names
// ------------------
ResultsGridView.HeaderRow.Cells[0].Text = "Select";
}
}
}
}
catch (SystemException ex)
{
var exceptionUtility = new genericExceptions();
exceptionUtility.genericSystemException(
ex,
Server.MachineName,
Page.TemplateSourceDirectory.Remove(0, 1) + Page.AppRelativeVirtualPath.Remove(0, 1),
ConfigurationManager.AppSettings["emailSupport"],
ConfigurationManager.AppSettings["emailFrom"],
string.Empty);
}
}
My PageIndexChanging event I would usually call the loadGrid() but I do not have that situation. I have tried just adding ResultsGridView.DataBind() but get the error Sequence contains no elements.
protected void ResultsGridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
ResultsGridView.PageIndex = e.NewPageIndex;
** How Can I bind the Grid**
}
Try this..
session["somename"]=result;
protected void ResultsGridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
var somename=session["somename"].Tostring();
ResultsGridView.PageIndex = e.NewPageIndex;
ResultsGridview.Datasource=somename;
REsultsGridview.Databind();
}
I have a DataSource bound to a LookUpEdit. For example I have 2 columns FirstName and LastName and I want to set DisplayMember property to these two columns.
I found that I should subscribe to lookUp_CustomDisplayText() and edit display text property like this:
private void lookUpCompanyPerson_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
{
LookUpEdit edit = sender as LookUpEdit;
if (e.DisplayText != "")
{
e.DisplayText = e.DisplayText + " " + (string)e.Value;
}
}
but I did not understand what e.Value is and I want to display another column for selected row, not the valuemember of selected row.
This is how I bind the datasource to lookupedit:
private void populateComboBoxForCompanyPerson()
{
lookUpCompanyPerson.Properties.ForceInitialize();
bs = new BindingSource(myDataSet, "CompanyPerson");
lookUpCompanyPerson.Properties.DataSource = bs;
lookUpCompanyPerson.Properties.DisplayMember = "CompanyName";
lookUpCompanyPerson.Properties.ValueMember = "PersonID";
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("PersonID"));
this.lookUpCompanyPerson.Properties.Columns["PersonID"].Visible = false;
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("FirstName"));
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("LastName"));
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("CompanyName"));
}
And this is what my datasource looks like:
I've changed Ian O'Brien's code a little bit and it works:
private void lookUpCompanyPerson_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
{
RepositoryItemLookUpEdit props;
if (sender is LookUpEdit)
props = (sender as LookUpEdit).Properties;
else
props = sender as RepositoryItemLookUpEdit;
if (props != null && (e.Value is int))
{
DataRowView row = props.GetDataSourceRowByKeyValue(e.Value) as DataRowView;
if (row != null)
{
e.DisplayText = String.Format("{0} {1}", row["FirstName"], row["LastName"]);
}
}
}
From the DevExpress documentation:
e.Value gets or sets editor's current value.
e.DisplayText gets or sets an editor's display text
The lookup editor's value is obtained from the data source field specified by the RepositoryItemLookUpEditBase.ValueMember property. The GetDataSourceRowByKeyValue method searches for the specified value within this field and returns an object representing the first found record.
The GetDataSourceRowByKeyValue method's return value depends upon the type of the underlying data source. If the data source is a System.Data.DataTable or a System.Data.DataView, this method returns a System.Data.DataRowView object. If the data source is a custom list of items, the appropriate list item is returned.
You want to set the e.Value to the value that you want to display in the control.
private void lookUpCompanyPerson_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
{
RepositoryItemLookUpEdit props
if (sender is LookUpEdit)
props = (sender as LookUpEdit).Properties;
else
props = sender as RepositoryItemLookUpEdit;
if (props != null && (e.Value is int))
{
object row = props.GetDataSourceRowByKeyValue(e.Value);
if (row != null)
{
e.Value = String.Format("{0} {1}", (DataRowView)row["FirstName"], (DataRowView)row["LastName"]);
e.Handled = true;
}
}
}
Finally, here are some useful pages with more documentation:
BaseEdit.CustomDisplayText Event
RepositoryItemLookUpEdit.GetDataSourceRowByKeyValue Method
i have use it, just like this;
cmb_tip.Properties.DataSource = _dt;
cmb_tip.Properties.ValueMember = "Value";
cmb_tip.Properties.DisplayMember = "Type";
cmb_tip.Properties.PopulateColumns();
cmb_tip.Properties.Columns["Value"].Visible = false;
This is how it works with LookupEditControl in Version 15.2.7 and a Class:
private void lookUpEditPatients_CustomDisplayText(object sender, DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs e)
{
var edit = sender as LookUpEdit;
var props = edit.Properties;
var pat = (Patients4ComboBoxVm) props?.GetDataSourceRowByKeyValue(e.Value);
if (pat != null)
{
e.DisplayText = pat.Nachname + ", " + pat.Vorname + "; " + pat.Geburtsdatum + "; " + pat.Versicherungsnummer;
}
}