ASP.NET GridView update Source but not commands - c#

I have a gridview. Its datasource is taken from XML by adding some xmlElemens in a list and than set the list as its data source. Now I am implementing a search feature.
So I am filtering the list in this way:
protected void btnSearch_Click(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load(prog); //Percorso file xml
List<string> nomi = new List<string>();
XmlElement root = doc.DocumentElement;
XmlNodeList elemLists = root.GetElementsByTagName("nome");
// this binds the gridview to the title text to display
for (int i = 0; i < elemLists.Count; i++)
{
if(elemLists[i].InnerXml.ToString().ToLower().StartsWith(txtSearchMaster.Text.ToLower()) ||
elemLists[i].InnerXml.ToString().ToLower() == txtSearchMaster.Text.ToLower() ||
elemLists[i].InnerXml.ToString().ToLower().EndsWith(txtSearchMaster.Text.ToLower()) ||
elemLists[i].InnerXml.ToString().ToLower().Contains(txtSearchMaster.Text.ToLower()))
nomi.Add(elemLists[i].InnerXml.ToString());
}
GridView1.DataSource = nomi.OrderBy(q => q).ToList();
GridView1.DataBind();
}
The data is shown correctly but the problem is that when I click the button next the column that is auto generated and get the cell content (that is an element of the list) it return the content of the cell at the same index but of the previous data.
How can I overcome to this?

The problem here is that your "filter" as it were is only applied on the search click. If you had hidden state where a search term was stored, and applied it on every postback, if the state exists, then clicking your grid button would work.
<asp:HiddenField ID="SearchString" runat="server" value="" />
and in your btnSearch_Click
SearchString.Value = txtSearchMaster.Text.ToLower().Trim();
and then add the filter logic in Page_Load
if (IsPostBack) {
// filter on hidden value if not empty.
if (!String.IsNullOrEmpty(SearchString.Value)) {
// filter here
}
}

Just fixed by adding
if (!IsPostBack)
{
...
}
in Page_Load and leaving the filter login into the search button click method.

Related

Populating around 10 Gridviews using one data source ASP C#

I need to display data from one table to 10 gridviews based on a filter value (column).
Lets say colours. So pink grid view should only show items that have Pink in colour column.
At the moment I have one Gridview bound (in ASP) to one Datasource. I am updating the datasource in codebehind.
Something like this:
String selectcommand = Select * from table where subject = "Pink"
sqlDatasource1.SelectCommand= (selectcommand);
mygv.Bind();
Obviously it would be a very bad idea to repeat the same code 10 times, one for each subject. Is there a better way of doing what I am after.
Main question is can I use the same datasorce with many gridviews after changing the colour?
Solution One
I bind all gridviews to one datasource and not bother about filtering by colour.
Then in gridview rowdatabound event of each gridview add something like this
if e.Row.RowType = DataControlRowType.DataRow Then
if e.Row.DataItem("colour") = "pink" then e.Row.visible = False
Any other suggestions?
You're right that duplicating the code would not be an ideal choice. However, as mentioned in the comments, you can make use of a repeater that loops over a grouped set of data (So you only query the database once), and then internally binds a GridView template.
The Aspx code could look like the following:
<asp:Repeater ID="repColors" OnItemDataBound="repColors_ItemDataBound" runat="server">
<ItemTemplate>
<asp:GridView ID="gvColor" runat="server" />
</ItemTemplate>
</asp:Repeater>
The Repeater has an OnItemDataBound that will be used to find and bind the GridView inside of its ItemTemplate. This GridView is simple, but could be as complex as you need it to be for your use case.
The aspx.cs page will contain the code you need to load all of your subjects into the repeater and then bind the gridview using the OnItemDataBound event handler.
protected void Page_Init(object sender, EventArgs e)
{
var data = GetColors();
var dataByColors = data.ToLookup(c => c.Subject, StringComparer.OrdinalIgnoreCase);
repColors.DataSource = dataByColors;
repColors.DataBind();
}
protected void repColors_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var gv = e.Item.FindControl("gvColor") as GridView;
gv.DataSource = e.Item.DataItem;
gv.DataBind();
}
}
public class Colors
{
public string Text { get; set; }
public string Subject { get; set; }
}
private IEnumerable<Colors> GetColors()
{
yield return new Colors { Text = "Color1", Subject = "Blue" };
yield return new Colors { Text = "Color2", Subject = "Pink" };
yield return new Colors { Text = "Color3", Subject = "Blue" };
yield return new Colors { Text = "Color4", Subject = "Red" };
yield return new Colors { Text = "Color5", Subject = "Pink" };
}
Page_Load is used to fetch all of your data from the database. Then we use LINQ to group it by Subject which generates objects that look something like:
{"Blue": {Color1, Color3}}
{"Pink": {Color2, Color5}}
{"Red": {Color4}}
This is then bound to the repeater. The repeater's ItemDataBound event takes each individual data item (Which is a key and a list of colors) and binds it to the GridView that it's able to find in the Repeater template. The ILookup interface will by default enumerate over the list of items that it maintains. This allows it to be passed directly to the GridView.DataSource and we don't need to worry about trying to cast it to a List or anything.

Title of DropDownList's items is not shown in Chrome v.43

After a long time searching for this problem I've decided to try my luck here... I'm trying to add a tooltip (title) for the items in a Drop Down List.The title is showed in IE and Firefox browsers. The DDL is creating dynamically and the DDL's DataSource is a list called "labCourses" .This is my code:
protected void Page_Load(object sender, EventArgs e)
{
ExpScheduleClass ExpSC = new ExpScheduleClass();
List<string> labCourses = ExpSC.getCourseList();
// dynamically create a dropdown list (aka DDL)
DDLCourses = new DropDownList();
DDLCourses.DataSource = labCourses; // set the data source
DDLCourses.DataBind(); // bind the data to the DDL control
BindTooltip(DDLCourses);
DDLCourses.AutoPostBack = true;
DDLCourses.SelectedIndexChanged += DDLCourses_SelectedIndexChanged;
coursePH.Controls.Add(DDLCourses);
}
public void BindTooltip(ListControl lc)
{
for (int i = 0; i < lc.Items.Count; i++)
{
lc.Items[i].Attributes.Add("title", lc.Items[i].Text);
}
}
I looked at the option element with the web inspector and the title was there (in the html), but is does not shown when the mouse was over the option.
In other browsers the title is shown on mouse hover. What may be the cause for this? Thank you very much...

Show the page with particular item in RadGrid

I have a RadGrid that I supply with data using DataSourceID. The RadGrid has paging, and I want to show the page containing some particular item. To do this, I find the offset of the item in the data and set the page number:
var index = dataSource.Count(t => t.Id > _selectedTickId);
var page = index / rgTicks.PageSize;
rgTicks.CurrentPageIndex = page;
My question is where to put this code. In the OnDataBound I don't seem to have access to the data source. If I put it in the OnSelecting the retrieving of data has a side effect of setting the page number. Should I extend the GridTableView to implement this functionality? Which method should I override?
I will suggest to compute index value in OnSelecting (which is data dependent) while page index can be set in OnDataBound or PreRender event.
My usecase was to jump to an item that was just inserted using a popup editor. Here's how I solved it. I am omitting non relevant properties in the tag. All the data wiring is up to you, but here are the relevant bits. Important: use DataKeyNames to avoid messy digging in the GridDataItem for a value.
In the page I have:
<telerik:RadGrid ID="rgItems" runat="server" AllowPaging="true"
OnNeedDataSource="rgItems_NeedDataSource"
OnPreRender="rgItems_PreRender"
OnInsertCommand="rgItems_InsertCommand">
<MasterTableView
CommandItemDisplay="Top"
CommandItemSettings-AddNewRecordText="Add New Item"
CommandItemSettings-ShowAddNewRecordButton="True"
DataKeyNames="IntItemId"
EditMode="popup"
EditFormSettings-PopUpSettings-Modal="true">
And in code behind:
private bool itemInserted = false;
protected void rgItems_InsertCommand(object sender, GridCommandEventArgs e)
{
itemInserted = true;
}
protected void rgItems_PreRender(object sender, EventArgs e)
{
if (itemInserted)
{
// Select the record and set the page
int LastItem = 0; // Put code to get last inserted item here
int Pagecount = rgItems.MasterTableView.PageCount;
int i = 0;
GridDataItem GDI = null;
while (i < Pagecount)
{
rgItems.CurrentPageIndex = i;
rgItems.Rebind();
GDI = rgItems.MasterTableView.FindItemByKeyValue("IntItemId", LastItem);
if (GDI != null) break; // IMPORTANT: Breaking here if the item is found stops you on the page the item is on
i++;
}
if (GDI != null) GDI.Selected = true; // Optional: Select the item
itemInserted = false;
}
}

ASP.Net: GridView control and combobox woes

I've got a GridView control and Combobox control that are both successfully populated in my Page_Load event (within a block that checks for IsPostBack == false).
I've got an empty button 'btnClick' event handler which will reload the page when clicked. Both the GridView and Combobox controls have their EnableViewState property set to True. The behaviour I was expecting and hoping for was:
Page will reload with the GridView control still populated.
Page will reload with Combobox still populated and the item selected by the user still set as the selected item.
Unfortunately, the behaviour I'm getting is as follows:
GridView control is now empty and shows no data.
Combobox is now empty.
Code as follows:
public MyPage()
{
this.Load += new EventHandler(Page_Load);
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
DataAccessObj daObj = new DataAccessObj();
foreach (DataRow dataRow in daObj.GetAllData())
{
ListItem listItem = new ListItem(dataRow.ToString(), dataRow.Id.ToString());
myCombobox.Items.Add(listItem);
}
IncidentGrid.DataSource = daObj.GetIncidentsByReportedById(0);
IncidentGrid.DataBind();
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
// Do nothing
}
What I would like to do is allow the user to select an item from the Combobox. Upon clicking Submit, the GridView would be repopulated (based upon the selected item). The Combobox will remain populated and show the last selected item.
Can someone help explain where I might be going wrong? TIA
When you click your button, the page is posted back, in your page load, if it is a postback you need to databind the grid appropriately you need to add a condition to your page load event like
Firstly on your btn_click, you need to store the id selected with something like:
if (myCombobox.SelectedItem != null)
{
if (int.TryParse(myCombobox.SelectedItem.Value, out reportedById) == false)
{
reportedById = 0;
ViewState["reportedById"] = reportedById; // Need to remember which one was selected
}
}
Then On your Post Back
else (IsPostBack)
{
if (ViewState["reportedById"]) != null)
{
IncidentGrid.DataSource = daObj.GetIncidentsByReportedById(Convert.ToInt32(ViewState["reportedById"]));
IncidentGrid.DataBind();
myCombobox.SelectedItem.Value = ViewState["reportedById"].ToString(); // set combo
}
else
{
IncidentGrid.DataSource = daObj.GetIncidentsByReportedById(0);
IncidentGrid.DataBind();
}
}

Dropdownlist first value display "choose"

I want that my dropdownlist display first value: "-choose car-"
I succeed at this way:
protected void ddl1_DataBound(object sender, EventArgs e)
{
Convert.ToInt32(ddl1.SelectedValue);
ddl1.Items.Insert(0, new ListItem("-Choose car-", "-Choose car-" ));
}
and that's ok,the "-choose-" is in the first place but the problem now is that if I have values,for example,the dropdownlist show like that:
-Choose car-
Subaro
Fiat
Honda
The first value that display when I'm enter to the site is the Subaro,and to see the -choose car- the user need to open the dropdownlist and then he will see the -choose car- at the first place.How can I do that from the start,from the page load - the -choose car- will display at the ddl from the page load.Where I wrong at the code ?
I tried the itemlist with AppendDataBoundItems = "true" but I got an error, and when I succeed,the problem is the same like I said before.
You were on the right track with using the AppendDataBoundItems property, it should be set to true if you're databinding the list.
Your markup should look like this
<asp:DropDownList runat="server" ID="ddl1" AppendDataBoundItems="true">
<asp:ListItem Text="-Choose car-" />
</asp:DropDownList>
and your code behind probably already looks something like this
ddl1.DataSource = [your datasource goes here];
ddl1.DataBind();
This will place the Choose car text as the first option in the drop-down list and append the rest of the options below it.
Now for the more interesting part of why you were seeing the behavior you were seeing (first item not being selected). If you look at the implementation of SelectedIndex using a tool like JustDecompile (not affiliated with Telerik, just happen to use their tool) you'll see code that looks like this:
public int SelectedIndex
{
get
{
int num = 0;
num++;
while (num < this.Items.Count)
{
if (this.Items[num].Selected)
{
return num;
}
}
return -1;
}
set
{
// stuff you don't care about
this.ClearSelection();
if (value >= 0)
{
this.Items[value].Selected = true;
}
// more stuff you don't care about
}
}
As you can see, the index isn't stored anywhere, it's computed every time based on which item has the Selected property set to true. When you set the SelectedIndex to 0 in the markup and databind your datasource, it will select the 0th item in that list, in your case Subaro. When you insert a new item at the beginning of the list, Subaro is still marked as the selected item, which is why when the page loads, you see that selected and not Choose car. If you want to mark Choose car as the selected item using code, you will have to do it after you data databind your dropdown. Please note, this is just an implementation detail of how DropdownList works. It could change in future version of ASP.NET so do not write code that relies on it working this way.
Make sure that you bind the data source and insert you "-choose care-" item first before selected he first item
make sure when you insert your 1st item "-Choose car-" you make it once not on each PostBack. Check if not IsPostBack to add the 1st item.
EDIT:
Example:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
ddl1.Items.Insert(0, new ListItem("-Choose car-", "-Choose car-" ));
}
ddl1.SelectedIndex = 0;
}
You should do ddl1.Items.Insert(0, new ListItem("-Choose car-", "-Choose car-")); first, and than ddl1.SelectedIndex = 0
private void FillCar()
{
DataTable dt = GetCar();
ddl1.Items.Clear();
ddl1.DataSource = dt;
ddl1.DataTextField = "carName"; // field name in the database
ddl1.DataValueField = "CarNum"; // field name in the database
ddl1.DataBind();
ListItem li = new ListItem();
li.Text = "--Choose car--";
li.Value = "-1";
ddl1.Items.Insert(0, li);
ddl1.SelectedIndex = 0;
}
I use method like this and call it in the page load in if (!IsPostBack){}.

Categories