DataFormatString from a dataset, by code - asp.net

I have selected a bunch of data from my access database which one of the fields is a DateTime field.
I'm trying to show it formated in a GridView but when I try:
dtlJob.DataSource = genericDataSet
dtlJob.Fields(2).DataFormatString = "{0:d}"
dtlJob.DataBind()
I get this error on line 2
Error 2 'DataFormatString' is not a member of 'System.Web.UI.WebControls.DataControlField'.
How do I format my data?
EDIT
This is my DetailsGridView I'm trying t o show off
<asp:DetailsView ID="dtlJob" runat="server" Height="50px" Width="125px">
</asp:DetailsView>
it has nothing but its tags for I'm fetching every data by code from a database. But I want to format the Data Date Field which is appearing like this no more which data it has

You have to create a BoundField like the code below.
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="false" Height="50px" Width="125px">
<Fields>
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField DataField="Age" HeaderText="Age" />
<asp:BoundField DataField="Birth" HeaderText="Birth" DataFormatString="{0:d}" />
</Fields>
</asp:DetailsView>
I hope that helped.
Vicente

The fields property is readonly, so you can't modify it except in constructor.
Please notice that I have not tested this solution, bt this is what I think you have to do.
So you have to create a new class that inherits from details view and shadows the Fields property, using its own private _fields field:
Imports System.Web.UI.WebControls
Public Class CustomDetailsView
Inherits DetailsView
Private _fields As System.Web.UI.WebControls.DataControlFieldCollection
Public Shadows Property Fields As System.Web.UI.WebControls.DataControlFieldCollection
Get
Return _fields
End Get
Set(ByVal value As System.Web.UI.WebControls.DataControlFieldCollection)
_fields = value
End Set
End Property
End Class
Then you have the following code, creating a CustomDetailsView object, telling it that its datasource is the dataset, formatting the second column field, and giving all hese information to your detaisview on the web form, before binding the data.
Dim myDetailsView = New CustomDetailsView
myDetailsView.DataSource = genericDataSet
CType(myDetailsView.Fields(1), BoundField).DataFormatString = "{0:d}"
dtlJob = myDetailsView
dtlJob.DataBind()
BoundField's base type is DataControlField, so you can write the CType line.
I can't test this right now, please do it and post feedback. If it doesn't work, it could be a beginning of answer.
Greetings

Here is an another solution (still not tested). Here you still make a new class inheriting DetailsView, and you access the fields variable in the constructor:
Imports Microsoft.VisualBasic
Imports System.Collections.Generic
Public Class _CustomDetailsView
Inherits DetailsView
Public Sub New(ByVal Columns As List(Of String))
For Each item As String In Columns
Dim bfield As New BoundField
If Not String.IsNullOrWhiteSpace(item) Then
bfield.DataFormatString = item
Else
bfield.DataFormatString = ""
End If
Me.Fields.Add(bfield)
Next
End Sub
End Class
Then, you create a list of string containing the wanted formatting for each column. Then you create your _CustomDetailsView by passing this list of string in the constructor.
Next you assign your DtlJob the _CustomDetailsView object, and finally you provide the datasource and proceed the databinding:
Dim DataFieldStyles = New List(Of String)
' First column: Default style
' Second column: Date format
' Third : Currency Format
' Fourth : Default style
DataFieldStyles.AddRange(New String() {"", "{0:d}", "{0:c}", ""})
Dim My_DetailsView As _CustomDetailsView = New _CustomDetailsView(DataFieldStyles)
dtlJob = My_DetailsView
dtlJob.DataSource = genericDataSet
dtlJob.DataBind()
Same remark as for my other answer, I can't test this, so try it and please give feedback.
Greetings

Related

How to save a null datetime to SqlServer DB? not working

VS-Studio 2012 Web Express, ASP.NET, WebForms , VB , SqlServer , WebSite application having trouble saving a NULL value for DateTime to the strongly typed ROW:
Dim oRowVEHICLES As Main_TblAdap.tVEHICLESRow = odtVEHICLES.Rows(0) ' (0) is the first row.
oRowVEHICLES.[WElectrical] = If(WElectrical.Year < 10, DBNull.Value, WElectrical)
...etc...
Currently the DetailsView template field textbox is < blank> or empty or "" and the BLL function shows it as a date like: #01/01/0001#. So I test the YEAR value of the passed in variable if less than 10 then save DBNull.Value to the oRowVehicles.[WElectrical] but fails since datatype=Date and cannot convert DBNull to Date.
The DB-field is type Date and allows nulls.
The TableAdapter.xsd view shows the default value is < DBNULL>.
So, why is the oRowVehicles not Date nullable?
How do I make the WElectrical column nullable DATE?
I must be overlooking something, because I cannot be the only one to save an optional DATE value to the Sql-DB.
Your comments and solutions are welcome. Thanks...John
EDIT
ASPX code one DATE field in the DetailsView (others are similar):
<asp:TemplateField HeaderText="Electrical End Date" SortExpression="WElectrical">
<EditItemTemplate>
<TGADate:GADate ID="ucdtWElectrical" runat="server" Enabled="True" MinDate="01/01/1980" MaxDate="12/31/2050"
Caption="Electrical End Date" HideCaption="True" Width="100"
IsRequired="false"
UpdateMode="Conditional"
Text='<%# Bind("WElectrical")%>' />
</EditItemTemplate>
<InsertItemTemplate>
<TGADate:GADate ID="ucdtWElectrical2" runat="server" Enabled="True" MinDate="01/01/1980" MaxDate="12/31/2050"
Caption="Electrical End Date" HideCaption="True" Width="100"
IsRequired="false"
UpdateMode="Conditional"
Text='<%# Bind("WElectrical")%>' />
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="lblWElectrical" runat="server" Text='<%# clsGA_Lib1.fnGetDateTextFromObject(Eval("WElectrical"))%>' Style="font-weight: bold;"></asp:Label>
</ItemTemplate>
<ItemStyle Font-Bold="true" />
</asp:TemplateField>
Object DataSource parameter definition in the ASPX.
<asp:Parameter Name="WElectrical" Type="DateTime" />
BLL Code:
<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, False)> _
Public Function UpdateFromDetailsView(ByVal original_UID_VEHICLE As Int32, _
ByVal VehicleNbr As String, _
...other function parameter variables...
ByVal WElectrical As Date, _
...other function parameter variables...
) As Boolean
' Get the new VEHICLE-row instance to be updated.
Dim odtVEHICLES As Main_TblAdap.tVEHICLESDataTable = Adapter.GetVhclByVhclID(original_UID_VEHICLE)
If odtVEHICLES.Count <> 1 Then
' no matching record found, return false
Return False
End If
' Populate the values of the ROW.
Dim oRowVEHICLES As Main_TblAdap.tVEHICLESRow = odtVEHICLES.Rows(0) ' (0) is the first row.
With oRowVEHICLES
...setting row-field values...
.[WElectrical] = If(WElectrical.Year < 10, Nothing, WElectrical)
...etc...
End With
' Update the oRowVEHICLES.
Dim rowsAffected As Integer = Adapter.Update(odtVEHICLES)
' Return TRUE if precisely one row was INSERTED, otherwise false.
Return CBool(rowsAffected = 1)
End Function
Edit comment for above code
The WElectrical parameter coming into the BLL-function is a DATE with a value of #01/01/0001#.
The code to place the value into the ROW-object
.[WElectrical] = If(WElectrical.Year < 10, Nothing, WElectrical)
places Nothing as the row-object-field-value.
The Adapter.Update(odtVEHICLES) updates the Sql-DB.
So what is causing the #01/01/0001# value to be placed into the Sql-DB?
Sql-DB column definition
//////// end of Edit ///////////
do one thing:
change DBNull.Value to Nothing
Alternatively you can change the datatype in the dataset to System.Object, and
go to the properties of that data colm
then you can select '(Nothing)' in the dropdown.
set Null value to >> Nothing
Thanks to all commentators to the above question.
The solution is to change the Row-column-variable to this sentence which casts the Nothing to Date? (nullable) as follows...
.[WElectrical] = If(WElectrical.Year < 10, CType(Nothing, Date?), WElectrical)
AND -- Changed the dataset-column-definition (in the .xsd) as follows:
DataType ==> System.Object (not Date)
NullValue ==> (Nothing) (not Throw Exception)
My sincere thanks to all contributors -- since elements of each of their suggestions have contributed to this solution.
This is the solution for sending a nullable value into the DataRow-column.
Thank you for all your help.

GridView or Datagridview column specific culture

I'm creating a GridView which has a balance column.
Depending on the currency, I have to set its symbol to dollars or colones (my country´s currency).
I'm doing good with labels, but I cant find the way to set it on the grid, only to "Mon" and "Sal" columns. A grid can have both kind of currency (if the customer have one COLONES and one DOLARS account, but just one kind per row).
I dont care if i have to change to datagridview, as long as I can set the symbol.
I'd really appreciate your help.
<asp:gridview id="gvMovMesActual" runat="server" AutogenerateColumns="false">
<columns>
<asp:boundfield datafield="num" headertext="Num" />
<asp:boundfield datafield="desc" headertext="Desc"/>
<asp:boundfield datafield="fec" headertext="Fec" />
<asp:boundfield datafield="mon" headertext="Mon" DataFormatString="{0:C3}" />
<asp:boundfield datafield="sal" headertext="Sal" DataFormatString="{0:C3}" />
</columns>
</asp:gridview>
Private Function setCulture (ByVal pcurrency as string) As System.IFormatProvider
Dim cultura as System.IFormatProvider
Select Case pcurrency
Case "COLONES"
cultura= CultureInfo.CreateSpecificCulture("es-CR")
Case "DOLARES"
cultura = CultureInfo.CreateSpecificCulture("en-US")
End Select
return cultura
End Function
Private Sub getMovs()
Dim ds as DataSet = New DataSet
ws = New WebserviceToBringData
ds= ws.bringsOkTheData()
if ds is not nothing then
gvMovMesActual.dataSource = ds
gvMovMesActual.DataBind()
end if
End Sub
Following is a solution given to a similar situation like yours.
multibinding
Since you have also asked for DataGridView...
Use the DefaultCellStyle.FormatProvider property of DataGridViewColumn to set specific cultures for individual columns.
DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
col.DefaultCellStyle.FormatProvider = CultureInfo.CreateSpecificCulture("en-CR");

Asp.net VB Test value in GridView

I have found heaps of solutions for this in C# but when you are dealing with FindControls and trying to pull a value out of the GridView the C# doesn't help and the translated code doesn't work.
I have this gridview:
<asp:GridView ID="WIPListGrid" runat="server" DataSourceID="WIPDataSource"
CssClass="site" AutoGenerateColumns="False"
Width="95%" DataKeyNames="Masterid_Action" onrowdatabound="WIPListGrid_RowDataBound">
<Columns>
<asp:BoundField DataField="Action Due Date" HeaderText="Action Due Date"
SortExpression="Action Due Date" />
</Columns>
</asp:GridView>
and I have this in vb:
Protected Sub WIPListGrid_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles WIPListGrid.RowDataBound
Dim DueDate As Label = DirectCast(e.Row.FindControl("Action Due Date"), Label)
'do what ever you want to do here using the value of your label
MsgBox("Due Date = " & DirectCast(e.Row.FindControl("Action Due Date"), Label))
End Sub
Error message is Operator & is not defined for types 'String' and 'System.Web.UI.WebControls.Label'
This is a remedial example of what I ~really~ want to do. Above I just want to display what is contained in DueDate to see what format it is in so I can test it against other values. but it won't work. It appears the the contents of Action Due Date is not a string... so, what am I missing?
I have tried to set the value equal to a string but got the same problem, the Label isn't a string...
How do I find out what's in there in order to evaluate it?
17/01/2013 edit: Keeping this active as I still do not have my issue resolved.
18/01/2013 edit:
vb.net code is now
Protected Sub WIPListGrid_ROWDataBound(sender as Object,
e As System.Web.UI.Webcontrols.GridViewRowEventArgs) Handles WIPListGrid.RowDataBound
Dim DueDate As Label = DirectCast(e.Row.FindControl("Action Due Date"), Label)
'do what ever you want to do here using the value of your label
MsgBox("Due Date = " & DueDate.Text)
End Sub
But now I get an error that the Object isn't instantiated and its pointing to the msgbox line in the code. I thought that I instantiated it when I dim it as a Label...
The official error is:
"Object reference not set to an instance of an object."
the troubleshooting tips say to
1) Use the "new" keyword to create an object instance
2) Check to determine if the object is null before calling the method
I tried the "new" option and got an error that says the variable has already been declared.
So now I want to check to determine if the object is null and can't figure out how.
I've tried testing: DirectCast(e.Row.FindControl("action due date"), Label) <> ""
but got an error: Overload resolution failed because no accessible '<>' can be called with these arguments.
How do I test to see if the object is null?
The value shouldn't be null (the database doesn't allow it to be null), BUT this could be the crux of my issue...
Any help?
When working with controls, you have to point out that you want that value inside your control.
In your case, you're just going for the label-control itself (not the text inside).
For example:
Dim myControl As Label = DirectCast(e.Row.FindControl("myControl"), Label)
MsgBox("MyText = " & myControl.Text)
Hope this helps.
The problem is you are using a BoundField so there is no control to find. Change it to a templatefield and this will work.
<asp:GridView ID="WIPListGrid" runat="server" DataSourceID="WIPDataSource"
CssClass="site" AutoGenerateColumns="False"
Width="95%" DataKeyNames="Masterid_Action" onrowdatabound="WIPListGrid_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Action Due Date">
<ItemTemplate>
<asp:Label ID="lblActionDueDate" runat="server" Text='<%# Bind("[Action Due Date]") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
For Your Row DataBound Event use
Dim DueDateLabel As Label = DirectCast(e.Row.FindControl("lblActionDueDate"), Label)
'Check Label Exists
If DueDateLabel IsNot Nothing Then
Dim DueDateText As String = DueDateLabel.Text
MsgBox(String.Format("Due Date {0}", DueDateText))
End If

System.ArgumentException: String value can not be converted to a date

I have a web form that uses an Ajax date calendar. This works fine. The problem that i have is that when i submit my form i get the following message.
'String value can not be converted to a date' .AgendaDate = New SmartDate(txtAgendaDate.Text)
Here is my web form that holds the calendar and the associated text box...
<td>
<asp:TextBox ID="txtAgendaDate" runat="server" ForeColor="Black" ></asp:TextBox>
</td>
<td>
<asp:ImageButton runat="Server" ID="ImageButton1" ImageUrl="~/images/calendarpic.png"
AlternateText="Click here to display calendar" />
<cc1:calendarextender ID="CalendarExtender1" runat="server"
TargetControlID="txtAgendaDate" PopupButtonID="ImageButton1" >
</cc1:calendarextender>
</td>
I have a class with the associated properties on it for the web form. The rest of the fields work and submit data to the database except the textfield for the ajax calendar.
Here is my stripped down version for the code for the class and the txtAgendaDate code...
#Region " Agenda Variables "
'Declare Variables and data types and set default values
Private mAgendaID As Integer = 0
Private mOrganiser As String = ""
Private mMeeting As String = ""
Private mAgendaDate As SmartDate = New SmartDate()
#End Region
#Region " Constructors "
Public Sub New()
End Sub
Public Sub New(ByVal reader As SafeDataReader)
' Public Sub New(ByVal reader As SQLDataReader)
'Combine variables & property types
With reader
mAgendaID = .GetInt32("AgendaID")
mOrganiser = .GetString("Organiser")
mMeeting = .GetString("Meeting")
mAgendaDate = .GetSmartDate("AgendaDate")
End With
End Sub
#End Region
#Region "Properties"
'Define form field properies so that they can be used when adding the data to the database on the add button is pressed.
Public Property AgendaID() As Integer
Get
Return mAgendaID
End Get
Set(ByVal Value As Integer)
mAgendaID = Value
End Set
End Property
Public Property Organiser() As String
Get
Return mOrganiser
End Get
Set(ByVal value As String)
mOrganiser = value
End Set
End Property
Public Property Meeting() As String
Get
Return mMeeting
End Get
Set(ByVal value As String)
mMeeting = value
End Set
End Property
Public Property AgendaDate() As SmartDate
Get
Return mAgendaDate
End Get
Set(ByVal Value As SmartDate)
mAgendaDate = Value
End Set
End Property
#End Region
End Class
Here is my command that looks connects to the DB and at the stored procedure and also has the parameters.
Public Class Agenda_TempDAL
Public Shared Function AddAgenda_Temp(ByVal Agenda_Temp As Agenda_Temp) As Integer
'Declare i as integer as 0
Dim iAgendaID As Integer = 0
'Database conn, this is linked to the web config file .AppSettings
Using dbconnection As New SqlConnection(ConfigurationManager.AppSettings("dbconnection"))
dbconnection.Open()
'Command to state the stored procedure and the name of the stored procedure
Using dbcommand As SqlCommand = dbconnection.CreateCommand
With dbcommand
.CommandType = CommandType.StoredProcedure
.CommandText = "Stored_Proc_Name"
'Create parameter for AgendaID and output
Dim oParam As New SqlParameter
oParam.ParameterName = "#AgendaID"
oParam.Direction = ParameterDirection.Output
oParam.SqlDbType = SqlDbType.Int
'Create parameters for the remaining fields
.Parameters.Add(oParam)
.Parameters.AddWithValue("#Organiser", Agenda_Temp.Organiser)
.Parameters.AddWithValue("#Meeting", Agenda_Temp.Meeting)
.Parameters.AddWithValue("#AgendaDate", Agenda_Temp.AgendaDate.DBValue)
'Simply execute the query
dbcommand.ExecuteNonQuery()
End With
End Using
End Using
'Need to return the agendaID as an integer.
Return iAgendaID
End Function
End Class
And here is the code behind the button ion the web page. This is the page that causes the error based on the property / field. The problem lies on this line...
.AgendaDate = New SmartDate(txtAgendaDate.Text)
The whole code for the button is here...
Protected Sub btnAddAgendaTemplate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddAgendaTemplate.Click
'This works alongside the Class named Agenda_Temp which has the properties and DB connection assigned to it for each web form field.
Dim oAgenda_Temp As New Agenda_Temp
'Within the object Agenda_Temp Class use the properties defined.
'They are required to be defined in the Agenda_Temp/ app code so we can use them within here.
With oAgenda_Temp
.Organiser = txtOrganiser.Text
.Meeting = txtMeeting.Text
.AgendaDate = New SmartDate(txtAgendaDate.Text)
'Within the object Agenda_Temp class use the defined DAL which includes all the DC connect and stored procedures.
oAgenda_Temp.AgendaID = Agenda_TempDAL.AddAgenda_Temp(oAgenda_Temp)
End With
End Sub
End Class
I understand that its telling me that the string value cannot be converted to a date but i don't know hoe to resolve this as i am new to .net 2010?
Any help much appreciated.
Convert the string to a date before newing it:
From MSDN:
string date = "01/08/2008";
DateTime dt = Convert.ToDateTime(date);
Your's would become
DateTime dt = Convert.ToDateTime(txtAgendaDate.Text)
Then pass the date to your SmartDate constructor:
oAgenda_Temp.AgendaDate = new SmartDate(dt)
The final result:
With oAgenda_Temp
.Organiser = txtOrganiser.Text
.Meeting = txtMeeting.Text
.AgendaDate = New SmartDate(Convert.ToDateTime(txtAgendaDate.Text))
'Within the object Agenda_Temp class use the defined DAL which includes all the DC connect and stored procedures.
oAgenda_Temp.AgendaID = Agenda_TempDAL.AddAgenda_Temp(oAgenda_Temp)
End With
As others have pointed out, you need to convert the input value to a DateTime. I don't know what the SmartDate() function is doing, but the error message clearly indicates that the value cannot be converted to a date.
Secondly, I would add some validation to make sure that the input is valid before you submit the page. Use the RequiredFieldValidator and CompareValidator or RegularExpressionValidator:
<asp:TextBox ID="txtDate" runat="server" ... />
<asp:RequiredFieldValidator ID="reqDate" runat="server" ErrorMessage="Required" Display="Dynamic" ControlToValidate="txtDate"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="regDate" runat="server" ControlToValidate="txtDate" ErrorMessage="Please enter a valid date in the format (mm/dd/yyyy)" ValidationExpression="^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$"></asp:RegularExpressionValidator>

Gridview Linkbutton Code behind

Until now, I was working with VS 2003 and recently migrated to VS 2008. I am facing some peculiar problems.
In Vs 2003,I had a Datagrid, and one of the field was ButtonField(Link button). It was not a template field. The user clicks on the field and some data gets generated.
I have written a code, in Vb, like this, on dg_ItemCommand:
Strid = Ctype(e.commandsource,linkbutton).text
Now i want to use same method,for the gridview (I think datagrid is gridview in 2008). I wrote a code like this on dg_Rowcomand
Private Sub dgSampleCustomer_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles dgSampleCustomer.RowCommand
Try
Dim strid As String
Dim i As Integer
strid = CType(e.CommandSource, LinkButton).Text
...
It is throwing a error.
Unable to cast object of type 'System.Web.UI.WebControls.GridView' to
type 'System.Web.UI.WebControls.ButtonField'.
Can anybody help me out!
It looks like the source of the command is the GridView itself, not the button you are clicking. What you probably want to do is set this value you are looking for in the "CommandArgument" property of the Linkbutton. The markup would look something like this:
<asp:LinkButton ID="myLinkButton" runat="server"
CommandName="MyCommandName"
CommandArgument="MySpecialValue"
Text="Click Me" />
Then in the event you would simply:
' strid = "MySpecialValue"
strid = e.CommandArgument.ToString()
Instead of pulling the ID from the name of the control, you can now easily get it from the command. CommandName is optional in this particular case, but comes in handy if you have multiple buttons on a grid that do different things, such as "Edit" and "Delete". Then you can use the command name to handle each command in their own way in the same event:
If (e.CommandName = "Edit") Then
' Do Some Edit Code
End If
I'm wondering why you are trying to cast the command source to a LinkButton? If you would like to attach or otherwise send some kind of row-specific information to your button handler, you are able to do this with the CommandName and CommandArgument attributes of the ButtonField.
Like:
<asp:Gridview ID="...">
...
<columns>
<asp:buttonfield buttontype="Link"
commandname="Generate"
text="Generate"/>
...
</columns>
</asp:GridView>
This will be retrievable in the event handler by using:
if(e.CommandName=="Generate")
{
// Convert the row index stored in the CommandArgument
// property to an Integer.
string rowIndex = Convert.ToInt32(e.CommandArgument);
...
}
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowcommand.aspx
UPDATE: (use DataKeys)
Since e.CommandArgument returns a row index, and you want the ID, use the DataKeys collection, first add your ID column to the DataKeyNames collection...
<asp:GridView ... DataKeyNames="ID">
... and then retrieve the values from the DataKeys collection, like:
GridView sourceGridView = (GridView) e.CommandSource;
rowIndex = Convert.ToInt32(e.CommandArgument);
strID = sourceGridView.DataKeys[rowIndex]["ID"];
You can try this in your rowcommand event
Dim index = Convert.ToInt32(e.CommandArgument)
Dim row = dg.Rows(index)
'find your linkbutton in template field (replace "lnkBtn" with your's)
Dim myLinkButton = CType(row.FindControl("lnkBtn"), LinkButton)
Dim strid As String = myLinkButton.Text
Let me know if it helps.

Resources