problem binding to filtered dataview - asp.net

I'm having a problem with the dtaview. I'm dynamically creating new datacolumns, assigning them values, and adding them into my datatable. Before using a filter, this was fine when binding. All values appeared.
However, I have since chosen to reduce returned results by filtering (by letter), and my returned dataview doesn't seem to allow binding with the newly created data columns. I've mined into the filtered view, and can see that the values are present that I need.
I'm trying to avoid putting everything back into a table again after applying the filter. An sql query based on letter is out of the question, as the whole original table is sitting in view state.
Here are some code snippets:
--Firstly create new datacolumn
Dim ICount As System.Data.DataColumn = New System.Data.DataColumn
ICount.DataType = System.Type.GetType("System.String")
ICount.AllowDBNull = True
ICount.ColumnName = "ICount"
register.Columns.Add(ICount)
--integer value is first calculated and then put into the datatable row
row("ICount") = IntegerCount.ToString()
--filtered view is created from datatable (returned from viewstate)
Dim filteredView As New Data.DataView(pTable, FilterExpression, "Surname", Data.DataViewRowState.OriginalRows)
--view is bound
grd.DataSource = filteredView
grd.DataBind()
--Markup
<asp:TemplateField HeaderText ="ICount" SortExpression="ICount">
<ItemTemplate>
<asp:Label ID="IC" runat="server" Text='<%# Bind("ICount") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
All of the non dynamic datacolumns are fine. Mining into both the datatable and the filtered view show values are there.
Any help would be much appreciated!!!

Ok - fixed this.
The problem was that I wasn't using the dataset.
So instead of creating a new view, I should have done the following:
datTable = CType(ViewState("datTable"), System.Data.DataTable)
datSet.Tables.Add(datTable)
datView = datSet.Tables(0).DefaultView
datView.RowFilter = FilterExpression
grd.DataSource = datView
grd.DataBind()
All values are now coming through.

Related

Convert a gridview templatefield to pdf iTextSharp

I have a GridView which is programatically filled from the DB (not a SqlDataSource or such). There are 4 columns which are TemplateFields as I format their text. They are Dates and Times and this is the one of their TemplateField:
<ItemTemplate>
<asp:Label ID="Label1" Text='<%# FormatDate(Eval("tDate")) %>' runat="server"></asp:Label>
</ItemTemplate>
This is the function to format that date:
Function FormatDate(objTime As Object) As String
Dim d As String
If objTime.Equals(DBNull.Value) Then
d = ""
Else
d = Convert.ToDateTime(objTime).ToString("MM-dd-yyyy")
End If
Return d
End Function
I've been using the method in this Post which was converted to VB code from this to convert the GridView to a PDF using iTextSharp.
My issue is that I'm getting a Null Reference exception here when adding the GridView data to the PDF(inside the For Loops):
Dim lc As DataBoundLiteralControl = TryCast(gvReport.Rows(rowNo).Cells(colNo).Controls(0), DataBoundLiteralControl)
s = lc.Text.Trim()
And if I remove this If statement and just run the Else part here:
s = gvReport.Rows(rowNo).Cells(colNo).Text.Trim()
ph = New Phrase(s, FontFactory.GetFont("Arial", ReportTextSize, iTextSharp.text.Font.NORMAL))
mainTable.AddCell(ph)
These Date/Time columns show up as empty on the PDF while all other columns show up with no issues.
I'm very lost on how to resolve this issue and have been unsuccessful in finding a solution online.
While I wasn't able to fix the solution I was following up above, I found a different way to access data from a TemplateField:
Dim s As String = CType(gvReport.Rows(rowNo).FindControl("Label1"), Label).Text
This gives me access to the data in the specified column. Now I just need to figure out a way iterate through the row and get each of the different TemplateFields which will probably involve reworking my For loops and a Select Case statement.
You are getting Nothing because TryCast will store Nothing if it cannot cast the value.
In bound columns, the control is 0, but in an edit item template like that, it is 1.
So you have to change
Dim lc As DataBoundLiteralControl = TryCast(gvReport.Rows(rowNo).Cells(colNo).Controls(0), DataBoundLiteralControl)
to
Dim lc As Label = TryCast(gvReport.Rows(rowNo).Cells(colNo).Controls(1), Label)

Is it possible to have a DataColumn with a space in the name and how can I do it?

I have a DataTable that I am creating and binding to a GridView. Currently the headers do not have any spaces and it makes it hard to read. I want to space them out but I'm having a minor issue.
What I am trying to accomplish :
Dim dc As Data.DataColumn
dc = New Data.DataColumn("Updated Date", System.Type.GetType("System.String"))
dt.Columns.Add(dc)
What I currently have :
Dim dc As Data.DataColumn
dc = New Data.DataColumn("UpdatedDate", System.Type.GetType("System.String"))
dt.Columns.Add(dc)
I know that I can set the HeaderText in the columns declaration like below, but I won't know how any columns I am going to have. And would rather the columns be generated automatically.
<Columns>
<asp:BoundField DataField="UpdatedDate" HeaderText="Updated Date" />
</Columns>
You might not want to use the constructor, and instantiate a column. This way you can set a property like below:
Dim col As New GridViewColumn()
col.DisplayMemberBinding = New Binding("UpdatedDate")
col.Header = "Updated Date"
dt.Columns.Add(col)
Hope this is what you are looking for
I believe names should not contain spaces, unless you want to create yourself bigger problems later. You can generate the column titles automatically by writing a line of code that inserts a space every time there is a capital letter in the name.

ASP Stored Procedure to GridView

I am attempting to use an existing stored procedure to populate a gridview.
First, I execute the stored procedure and use a SqlAdapter to put it into a DataSet. I know this works because DataSet.Tables[0] contains my data. However, when I create a GridView and bind the data to the GridView, nothing is displayed.
Here is the code for binding the GridView:
DataSet ds = Execute_spr();
GridView testGridView = new GridView();
if (ds.Tables.Count > 0)
{
testGridView.DataSource = ds.Tables[0].AsEnumerable();
testGridView.DataBind();
}
and here is the code for my gridview in the .aspx page:
<asp:GridView ID="testGridView" runat = "server" AutoGenerateColumns = "true" />
Any idea what I might be doing incorrectly?
Edit: I have tried the ds.Tables[0] without AsEnumerable() and using .DefaultView
Why are you re-initialising the Gridview in the line
GridView testGridView = new GridView();
Create a protected member in your codebeind called "testGridView", remove the line above, and you might start to get somewhere...

Error: SelectedValue which is invalid because it does not exist in the list of items

I have a Gridview which binds to an ObjectDataSource (objStudentDetails). In edit/insert mode of the Gridview one of the fields is a DropDownList that gets it's pick list options from a lookup table. I have this DropDownList binding to another ObjectDataSource control (objStateList) which represents the lookup table. It works fine as long as the value in the objStudentDetails ObjectDataSource matches one of the values in the objStateList ObjectDataSource, at least in the case of a non empty string value anyway.
The objStateList has these values (from the stored proc that loads it - ID#6 is an empty string ''):
StateId State
----------- -----
6
4 AL
1 GA
3 KY
2 TN
The objStudentDetails has these values (from the stored proc that loads it):
FirstName LastName State
----------- ---------- -----
tone smith TN
Or it could have this result set (State is an empty string - ''):
FirstName LastName State
----------- ---------- -----
jenny johnson
In the first objStudentDetails resultset the state DropDownList in the EditItemTemplate shows up fine. In the second resultset, however, I get this error:
'ddlEditState' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value
I would think that since my lookup table has a value with an empty string, that the objStudentDetails value with an empty string for state would match, but something isn't working the way I am expecting it to.
Here is my EditItemTemplate code from the Gridview:
<EditItemTemplate>
<asp:Panel ID="panEditState" runat="server">
<asp:DropDownList ID="ddlEditState" runat="server" CssClass="GridviewDropdownlist"
DataSourceID="objStateList" DataTextField="State" DataValueField="State"
SelectedValue='<%# Bind("State") %>'
Width="50px">
</asp:DropDownList>
</asp:Panel>
</EditItemTemplate>
And the objStateList, which calls a method passing a parameter of which lookup table to query:
<asp:ObjectDataSource ID="objStateList" runat="server" SelectMethod="GetDropdownData" TypeName="AIMLibrary.BLL.DropdownData">
<SelectParameters>
<asp:Parameter Name="itemsToGet" DefaultValue="state" />
</SelectParameters>
</asp:ObjectDataSource>
Any ideas?
Start by setting both DropDownLists' AppendDataBoundItems property to true. Next, add the NULL ListItem by adding the following <asp:ListItem> element to each DropDownList so that the declarative markup looks like:
<asp:DropDownList ID="Categories" runat="server"
DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'
AppendDataBoundItems="True">
<asp:ListItem Value="">[nothing selected]</asp:ListItem>
</asp:DropDownList>
I suspect there are many different scenarios that can cause this error. In my case, I had a drop down placed in a template field. The drop down was bound to its own objectdatasource, and its selectedvalue property was bound to a field from the gridview's own (separate) datasource.
Now, with my specific scenario, the problem was a race condition. The gridview's datasource was being populated and bound BEFORE the dropdowns had their turn. This also meant that the dropdowns' selectedvalues were being set BEFORE the dropdowns' items had been created through their own bindings.
I'm sure there's got to be a better solution, but I didn't have much time for research. I disconnected the gridview and the dropdowns from their datasources (meaning, removing the assignments from the designer) and opted bind programmatically. That way, I can explicitly bind the dropdowns so that their items' values will be available when the gridview itself is bound.
So far, so good. Just a few extra lines of code in the Page_Load
AppendDataBoundItems="True"> works but not in all cases. Making dropdownlist inside GridView is still a mystery which Microsoft has to resolve. They say development is ASP is much quicker than PHP. Well this is my third day on this small problem and still have no solution.
OK, since this is a common problem I guess its worth to actually post an answer: After a lot of looking around I've found two solutions - well, one patch and one real one.
Patching:
Set the DDL setting AppendDataBoundItem=true anda add manually one element to the list (i.e. "Please Select" with null value):
< asp:DropDownList ID="DropDownList5 runat="server" AppendDataBoundItems="True" ... >
< asp:ListItem>Please Select< /asp:ListItem>
< /asp:DropDownList>
This seems to work in about 80% of cases. I had a weird situation when I had to upgrade existing (and working) query used by DDL to allow another value of parameter - Query was something similar to SELECT ID, Name from EMPLOYEES where Department =#Department and originally #Department could only be equal to "Planners" and "Workshop" - after adding "Logistics" DDL mysteriously stopped working ONLY for the new value of department.
Proper solution: Bind the DDL during the GridView_RowDataBound event (fount thanks to This article
My parameter is taken as a text from the label (set up somewhere else)
protected void GridView5_RowDataBound(object sender, GridViewRowEventArgs e)
{
//********** this is a workaround for the annoying problem with dropdownlist in gidview without adding new item ************
if (e.Row.RowType == DataControlRowType.DataRow && GridView5.EditIndex == e.Row.RowIndex)
{
DropDownList DropDownList5 = (DropDownList)e.Row.FindControl("DropDownList5");
string query = "SELECT gkey as empID, name FROM [employees] where department=#department";
SqlCommand command = new SqlCommand(query);
command.Parameters.AddWithValue("#department", lblDepartment.Text);
DropDownList5.DataSource = GetData(command);
DropDownList5.DataTextField = "name";
DropDownList5.DataValueField = "empID";
DropDownList5.DataBind();
}
And the GetData method:
private DataTable GetData (SqlCommand cmd)
{
string strConnString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt= new DataTable())
{
sda.Fill(dt);
return dt;
}
}
}
}

A Problem with changing width of a gridview column

I have a datatable binded with gridview and I want to change the column width.
This it the code I use:
DataTable aTable = new DataTable("Words");
aTable.Columns.Add("word");
GridView1.DataSource = aTable;
DataRow a = aTable.NewRow();
a[0] = "test";
aTable.Rows.Add(a);
GridView1.DataBind();
GridView1.Columns[0].ItemStyle.Width = Unit.Pixel(200);
When the execution gets to the last line it produces an error saying that the column with index 0 is not found, howerver it is in the datatable and it is shown in the webpage.
Why doesn't the gridview see the column and is there a way around this?
The column count will always be 0 unless you explicitly define <columns> in your gridview.
You are autogenerating. So use <columns> with <asp:BoundField DataField="word" />and it will work.
I'd try placing this in the grid view's prerender event. You may be trying to do this in the wrong spot.
EDIT Try adding this before your statement:
if(GridView1.Columns.Count > 0)
//do stuff here

Resources