Dropdown Not Rendering After Databinding - c#

I'm binding to a dropdown. It works on the initial load. On subsequent loads (postbacks) it doesn't refresh the items in the dropdown.
using (DataView dv = dtProductGroup.DefaultView)
{
dv.ApplyDefaultSort = false;
dv.Sort = "KVIGroupName ASC";
ddlGroup.ClearSelection();
ddlGroup.Items.Clear();
string strAll = Localization.GetResourceValue("_strddlStatusLBAll");
ddlGroup.DataValueField = "KVIGroupId";
ddlGroup.DataTextField = "KVIGroupName";
ddlGroup.DataSource = dv;
ddlGroup.DataBind();
ListItem item = new ListItem(strAll, "0");
ddlGroup.Items.Insert(0, item);
}
I've confirmed that on the postbacks the data is being bound to the dropdown and items are successfully added. But when the page renders the dropdown doesn't have any of the new values.
I see two possibilities: The control isn't rendering the new values or the values are being cleared. I'm at a loss of where to look for possible problems.
Edit
I discovered the problem. The dropdownlist was embedded in an Conditional UpdatePanel. Simply calling "UpdatePanel.Update();" solved the problem.

Upon Postback the viewstate is being reapplied + you said you're trying to load values again. I'd suggest letting viewstate carry all the weight on postback. Only load the values when the page is first hit by adding if (! IsPostBack) like so
using (DataView dv = dtProductGroup.DefaultView)
{
if (! IsPostBack) {
dv.ApplyDefaultSort = false;
dv.Sort = "KVIGroupName ASC";
ddlGroup.ClearSelection();
ddlGroup.Items.Clear();
string strAll = Localization.GetResourceValue("_strddlStatusLBAll");
ddlGroup.DataValueField = "KVIGroupId";
ddlGroup.DataTextField = "KVIGroupName";
ddlGroup.DataSource = dv;
ddlGroup.DataBind();
ListItem item = new ListItem(strAll, "0");
ddlGroup.Items.Insert(0, item);
}
}
Edit:
Also, your syntax ensures the DataView object referenced by dv is Disposed of when the code block exits. My second guess is this causes a side-effect that causes the problem.
using (DataView dv = dtProductGroup.DefaultView)
{
Instead leave out the using and write a regular declaratoin like the following (The DataView is going to be Disposed along with everything else when the page is done rendering so there's not really any need to do it yourself).
DataView dv = dtProductGroup.DefaultView;
See the MSDN documentation about 'using' and IDisposable for detailed info.

Related

Performance issues with loading a lot of data in datagridview

I created an application that needs a datagridview in order to display data, so i created a method that displays the data from MySQL database to the datagridview using datatable.
However when i started the application i noticed that the datagridview is lagging when i scroll left and right even tho my datagridview has around 20-30 record. My question here is how can i possibly enhance its performance since my client will load around 10k of data on it. Several thing i tried was i enabled the double buffer and still i didn't notice any enhancement.
My code so far:
void DisplayTable()
{
var connection = Connection.prevzemiKonekcija();
var adapter1 = new MySqlDataAdapter();
var sqlSelectAll = "SELECT * from prodavnica.artikli";
adapter1.SelectCommand = new MySqlCommand(sqlSelectAll, connection);
var table = new DataTable();
adapter1.Fill(table);
var bajndsors = new BindingSource();
bajndsors.DataSource = table;
dataGridView1.DataSource = bajndsors;
dataGridView1.RowsDefaultCellStyle.BackColor = Color.Linen;
dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.Cornsilk;
dataGridView1.Columns[0].HeaderText = "Ред.бр";
dataGridView1.Columns[1].HeaderText = "Шифра";
dataGridView1.Columns[2].HeaderText = "Назив";
dataGridView1.Columns[3].HeaderText = "Набавна цен.";
dataGridView1.Columns[4].HeaderText = "Продажна цен.";
dataGridView1.Columns[5].HeaderText = "Кол.";
dataGridView1.Columns[6].HeaderText = "Данок";
dataGridView1.Columns[7].HeaderText = "Опис";
dataGridView1.Columns[8].HeaderText = "Долг опис";
dataGridView1.Columns[9].Visible = false;
dataGridView1.Columns[10].HeaderText = "Ед.мера";
dataGridView1.Columns[11].HeaderText = "Профит";
dataGridView1.Columns[12].HeaderText = "Производител";
this.dataGridView1.VirtualMode = true;
connection.Close();
}
You really shouldn't be seeing any performance problems with only 20 or 30 rows of data, but the way to deal with that in a DataGridView is to implement virtual mode. You set the VirtualMode of the DGV to true, and implement a few event handlers (CellValueNeeded, maybe others) to get the data for a particular cell. Your data is stored in some private structure, but is not data bound to the DGV.
Note that enabling virtual mode disables some other features of the DGV. Notably, sorting and autosizing column widths are not available, so if you need those features, you'll need to write your own implementations.
You can use a DataTable to store your data, which may be sufficient via the SQL query. I've found that using DataRow[] is faster than filling a whole table though.

Panel Does not update TreeView

I have a TreeView that is displayed inside a panel. The data in the TreeView is based on data returned from the database. The first time, the data is correct. The second time, the TreeView is not refreshed, and the previous data is still showing in the tree. I checked the list that contain the data. The list returned the correct data. I've Google the issue, and could not resolved it with some of the answers that were posted. Here is a sample code of how the TreeView is being created and added to the Panel.
ReportGroups gr = new ReportGroups();
var Name = gr.GetReportName(groupID);
TreeView tr = new TreeView();
tr.BeginUpdate();
tr.Size = new Size(570, 600);
tr.Name = "Home";
tr.Nodes.Add("Reports Name");
tr.CheckBoxes = true;
if (Name.Count() > 0)
{
foreach (var item in Name)
{
if (item != null)
{
tr.Nodes[0].Nodes.Add(item.reportName);
}
}
}
tr.Nodes[0].ExpandAll();
tr.EndUpdate();
this.pDisplayReportName.Width = tr.Width * 2;
this.pDisplayReportName.Height = 300;
this.pDisplayReportName.Controls.Add(tr);
this.pDisplayReportName.Refresh();
What am I doing wrong?
try to add this.pDisplayReportName.Clear(); so data will not double up. :)
The easy option would be to use this.pDisplayReportName.Controls.Clear(); just after tr.EndUpdate();. But, this would cause an issue if you have other controls within the same Panel.
The best option would be to use this.pDisplayReportName.Controls.RemoveByKey("MyTree"); instead of this.pDisplayReportName.Controls.Clear();
And, another option would be to add a TreeView in design time (with name tr) rather than dynamically to the panel. Then, use tr.Nodes.Clear(); before tr.BeginUpdate(); and remove following two lines from your code.
TreeView tr = new TreeView();
.
.
.
this.pDisplayReportName.Controls.Add(tr);
Cheers

asp.net Hide Specific items in dropdownlist using javascript

I'm using ASP.NET and I'm dynamically filling up my DropDownList.
Here is my code:
DataTable dtList = new DataTable();
dtList.Columns.Add("Name");
dtList.Columns.Add("Type");
foreach (DataDefinitionResponse dr in _dr)
{
if (dr.Type == "Dropdown")
{
string[] strSplit = dr.ListValue.Split('|');
List<string> lst = new List<string>();
foreach (string word in strSplit)
{
DataRow row = dtList.NewRow();
row["Name"] = word;
row["Type"] = dr.Name;
dtList.Rows.Add(row);
}
}
}
ddlFieldList.DataSource = dtList;
ddlFieldList.DataTextField = "Name";
ddlFieldList.DataValueField = "Type";
ddlFieldList.DataBind();
Now I just want to hide a specific item using Javascript when another DropDownList is selected.
I'm not using SelectedIndexChanged here. I must use Javascript.
Please someone help me with this.
Thx
I don't think you will be able to manipulate the DropDownList with JavaScript and "get away with it" because when the page is subsequently posted back to the server ASP .NET will detect that the DropDownList has been "tampered" with and will throw an exception.
There are flags you can set that stop the error but it is unlikely that you will then be able to use the DropDownList in your code-behind.
You would normally achieve what you are trying to do with SelectedIndexChanged (I know you said you didn't want to) and put the control in an UpdatePanel or similar to avoid a full page post-back / refresh.
function Remove()
{
var DropDownList=document.getElementById('<%=DropDownList1.ClientID%>');
alert(DropDownList.value);
for(i=DropDownList.length-1; i>=0; i--)
{
if(DropDownList.options[i].selected)
{
DropDownList.remove(i);
}
}
}

Programmatic Gridview Understanding

This may be a fairly simple question, but I can't seem to find the answer I'm looking for.
I've been working with a GridView control programmatically, loading it from a dataset in the code behind. So it's a fairly simple process, instantiate a new Gridview, load the Dataset, bind the data, and then load the control.
However, I'm running into an issue where I can't load directly into the GridView from the code. In the .aspx file I have a simple:
<asp:GridView ID="Supp_Data" runat="server" />
In the code behind my creation of the GridView is as follows:
Supp_Data = new GridView();
Supp_Data = OutsideClass.GetData(str_sql);
//Add other features here (such as AllowSorting, GridLines, PageSize, etc.)
Supp_Data.DataBind();
And in my outside class:
public static GridView GetData(string str_sql)
{
// string str_sql is simply the sql query that we will get the dataset with.
OdbcConnection dbc_conn = ODBC_Conn(""); //This simply instantiates the connection
OdbcCommand dbc_cmd = null;
OdbcDataAdapter dbc_adpt = null;
DataSet dta_ds = new DataSet();
GridView ret_val = new GridView();
try
{
if (dbc_conn.State != System.Data.ConnectionState.Open) { dbc_conn.Open(); }
dbc_cmd = new OdbcCommand(str_sql, dbc_conn);
dbc_adpt = new OdbcDataAdapter(dbc_cmd);
dbc_adpt.Fill(dta_ds);
ret_val.DataSource = dta_ds;
ret_val.DataBind();
dbc_conn.Close();
}
catch (Exception e)
{
string tst_msg = e.Message;
}
return ret_val;
}
But this doesn't display the grid at all.
Now, as a workaround (which displays the data), adding a PlaceHolder in the .aspx file and using PlaceHolder.Controls.Add(Supp_Data) displays the data just fine.
So my actual question is, why doesn't the data get displayed in the GridView, but has no problem displaying in the PlaceHolder? Does it have something to do with the Page Life Cycle that I'm overlooking (I tried with both Page_Load and Page_Init with the same results)? This would definitely help my overall understanding of this process. I just don't understand why it would work near perfectly with one but not with the other.
Thanks for any information.
You shouldn't do a 'new' on the GridView, just populate it's DataSource and call DataBind. The object that the page was referencing is being overwritten in your function call so it has nothing to display.

unable to edit DataGridView populated with results of LINQ query

When i use the results of a linq-to-xml query to populate a datagridview, i cannot edit the datagridview. i've tried setting the datagridview's readonly property to false and that doesn't help. I also added an event handler for cellBeginEdit and put a breakpoint there, but it doesn't get hit. Any idea what i'm doing wrong, or if this isn't possible?
public class MergeEntry
{
public string author { get; set; }
public string message { get; set; }
}
...
var query = from entry in xmlDoc.Descendants("entry")
select new MergeEntry
{
author = entry.Element("author").Value,
message = entry.Element("msg").Value,
}
var queryAsList = query.ToList();
myBindingSource.DataSource = queryAsList;
myDataGridView.DataSource = myBindingSource;
Yes, it is possible to bind to a list created from Linq-To-Xml. I tried to reproduce your problem. I did the following:
Created an empty WindForm project (VS 2008 and .Net 3.5)
Added a DataGridView to the Form.
Wired the CellBeginEdit and CellEndEdit.
Placed the following code in the Form's constructor
string testXML =
#"<p><entry>
<author>TestAuthor1</author>
<msg>TestMsg1</msg>
</entry></p>
";
XElement xmlDoc = XElement.Parse(testXML);
var query = from entry in xmlDoc.Descendants("entry")
select new MergeEntry
{
author = entry.Element("author").Value,
message = entry.Element("msg").Value,
}; //You were missing the ";" in your post, I am assuming that was a typo.
//I first binded to a List, that worked fine. I then changed it to use a BindingList
//to support two-way binding.
var queryAsList = new BindingList<MergeEntry>(query.ToList());
bindingSource1.DataSource = queryAsList;
dataGridView1.DataSource = bindingSource1;
When running the WinForm app, an editable grid was displayed and the CellBeginEdit and CellEndEdit events were fired when they should have been. Hopefully trying to reproduce using the above steps will help you locate the issue you are facing.
Since you're using ToList, your DataSource is actually a List<MergeEntry>, so the fact that it comes from a Linq query doesn't change anything. I suspect the ReadOnly property of the columns (not the DGV) is set to true... I see no other reason why the grid wouldn't be editable
This solution may not efficient but it works for me,
I moved all data (which is from LINQ) into a new collection and passed that new collection as datasource to gridview.
Now gridview allow us to edit cells.

Categories