htmlhelper inside webgrid - asp.net-mvc-3

I'm using MVC3 and I need a HTMLHelper with image, so I found a nice code, the problem is that the image is not shown instead of I see html code ex:
<a href='whatever'><img src="images/printer.png" /></a>
Maybe this is because the helper is inside a webgrid helper, I really don't know, any suggestion?
Helper
<Extension()> _
Public Function ActionLinkWithImage(ByVal helper As HtmlHelper, ByVal actionName As String, ByVal controllerName As String, ByVal imageUrl As String, ByVal alternateText As String, ByVal routeValues As Object, ByVal linkHtmlAttributes As Object, ByVal imageHtmlAttributes As Object) As String
Dim urlHelper = New UrlHelper(helper.ViewContext.RequestContext)
Dim url = urlHelper.Action(actionName, controllerName, routeValues)
' Create link
Dim linkTagBuilder = New TagBuilder("a")
linkTagBuilder.MergeAttribute("href", url)
linkTagBuilder.MergeAttributes(New RouteValueDictionary(linkHtmlAttributes))
' Create image
Dim imageTagBuilder = New TagBuilder("img")
imageTagBuilder.MergeAttribute("src", urlHelper.Content(imageUrl))
imageTagBuilder.MergeAttribute("alt", urlHelper.Encode(alternateText))
imageTagBuilder.MergeAttributes(New RouteValueDictionary(imageHtmlAttributes))
' Add image to link
linkTagBuilder.InnerHtml = imageTagBuilder.ToString(TagRenderMode.SelfClosing)
Return linkTagBuilder.ToString()
End Function
WebGrid load
#<div id="divGrid">
#grid.GetHtml(
tableStyle:="webgrid",
headerStyle:="webgrid-header",
footerStyle:="webgrid-footer",
alternatingRowStyle:="webgrid-alternating-row",
selectedRowStyle:="webgrid-selected-row",
rowStyle:="webgrid-row-style",
mode:=WebGridPagerModes.All,
firstText:="<< Inicio",
previousText:="< Anterior",
nextText:="Siguiente >",
lastText:="Fin >>",
columns:=grid.Columns(
grid.Column(format:=Function(Model) Html.ActionLink(" ", "Details", "CertificadoVehiculo", New With {.area = "Certificados", .parIDCertificado = Model.ID_CERTIFICADO, .parIDPoliza = Model.ID_POLIZA}, New With {.class = "imgConsultar", .title = "Consultar"}), style:="webgrid-width-images"),
grid.Column(format:=Function(Model) Html.ActionLink(" ", "Edit", "CertificadoVehiculo", New With {.area = "Certificados", .parIDCertificado = Model.ID_CERTIFICADO, .parIDPoliza = Model.ID_POLIZA}, New With {.class = "imgEditar", .title = "Modificar"}), style:="webgrid-width-images"),
grid.Column(format:=Function(Model) Html.ActionLinkWithImage("Action", "Controller", Url.Content("~/Images/printer.png"), "TextoAlternativo", Nothing, Nothing, Nothing), style:="webgrid-width-images"),
grid.Column("ID_CERTIFICADO", "No. Certificado"),
grid.Column("POLIZAS.NUMERO_POLIZA", "No. Poliza"),
grid.Column("PRIMER_APELLIDO_ASEGURADO", "Asegurado", format:=Function(Model) Model.ASEGURADOS.PRIMER_APELLIDO_ASEGURADO & " " & Model.ASEGURADOS.SEGUNDO_APELLIDO_ASEGURADO & " " & Model.ASEGURADOS.NOMBRES_ASEGURADO),
grid.Column("PRIMA_CERTIFICADO", "Prima Total"),
grid.Column("ESTADOS.DESC_ESTADO", "Estado")
)
)
</div>

Make the ActionLinkWithImage helper return MvcHtmlString instead of string. Like this:
<Extension()> _
Public Function ActionLinkWithImage(ByVal helper As HtmlHelper, ByVal actionName As String, ByVal controllerName As String, ByVal imageUrl As String, ByVal alternateText As String, ByVal routeValues As Object, ByVal linkHtmlAttributes As Object, ByVal imageHtmlAttributes As Object) As MvcHtmlString
Dim urlHelper = New UrlHelper(helper.ViewContext.RequestContext)
Dim url = urlHelper.Action(actionName, controllerName, routeValues)
' Create link
Dim linkTagBuilder = New TagBuilder("a")
linkTagBuilder.MergeAttribute("href", url)
linkTagBuilder.MergeAttributes(New RouteValueDictionary(linkHtmlAttributes))
' Create image
Dim imageTagBuilder = New TagBuilder("img")
imageTagBuilder.MergeAttribute("src", urlHelper.Content(imageUrl))
imageTagBuilder.MergeAttribute("alt", urlHelper.Encode(alternateText))
imageTagBuilder.MergeAttributes(New RouteValueDictionary(imageHtmlAttributes))
' Add image to link
linkTagBuilder.InnerHtml = imageTagBuilder.ToString(TagRenderMode.SelfClosing)
Return MvcHtmlString.Create(linkTagBuilder.ToString())
End Function

Related

ORA-01460: unimplemented or unreasonable conversion (after conversion of a docx to pdf and uploading to db) VisualBasic (VB)

i'm a junior developer and i started working recently.
They put me on this LEGACY program and asked me to try and resolve this problem.
They strictly forbid me of using CLOB.
Dim fs As Stream = PostedFile.InputStream
Dim br As New BinaryReader(fs)
Dim bytes As Byte() = br.ReadBytes(Convert.ToInt32(fs.Length))
pdfComunication = pdfConvert(bytes)
pdfComunication = bytes
idOperator = ViewState("idOperator")
'
Private Function pdfConvert(ByVal document As Byte()) As Byte()
Dim doc As Byte()
Using msRtf As MemoryStream = New MemoryStream(document)
Dim dc As softDocument.DocumentCore = softDocument.DocumentCore.Load(msRtf, New softDocument.DocxLoadOptions())
Using msDocx As MemoryStream = New MemoryStream()
dc.Save(msDocx, New softDocument.PdfSaveOptions())
doc = msDocx.ToArray()
End Using
End Using
Return doc
End Function
'
<WebMethod()>
Public Function InsertComunications(ByVal pIdComunicationType As Integer, ByVal pAwaitingStatus As Integer, ByVal pRequestingUser As String, ByVal pIdSr As String,
ByVal pItem As String, ByVal pText As String, ByVal pCommonSender As String, pPecSender As String, ByVal pDestination As String,
ByVal pPdfComunication As Byte()) As String
Dim dbConn As New OracleConnection
Dim cmd As New OracleCommand
Dim errMsg As String = String.Empty
dbConn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings("DBConn").ToString
Try
dbConn.Open()
cmd.Parameters.Clear()
cmd.CommandText = ""
cmd.CommandType = System.Data.CommandType.StoredProcedure
cmd.Connection = dbConn
Dim p_IdComunicationType As New System.Data.OracleClient.OracleParameter("p_IdComunicationType ", System.Data.OracleClient.OracleType.Number)
p_IdComunicationType.Direction = ParameterDirection.Input
p_IdComunicationType.Value = pIdComunicationType
cmd.Parameters.Add(p_IdComunicationType)
Dim p_AwaitingStatus As New System.Data.OracleClient.OracleParameter("p_AwaitingStatus", System.Data.OracleClient.OracleType.Number)
p_AwaitingStatus.Direction = ParameterDirection.Input
p_AwaitingStatus.Value = pAwaitingStatus
cmd.Parameters.Add(p_AwaitingStatus)
Dim p_RequestingUser As New System.Data.OracleClient.OracleParameter("p_RequestingUser ", System.Data.OracleClient.OracleType.NVarChar)
p_RequestingUser.Direction = ParameterDirection.Input
p_RequestingUser.Value = pRequestingUser
cmd.Parameters.Add(p_RequestingUser)
Dim p_IdSr As New System.Data.OracleClient.OracleParameter("p_IdSr", System.Data.OracleClient.OracleType.NVarChar)
p_IdSr.Direction = ParameterDirection.Input
p_IdSr.Value = pIdSr
cmd.Parameters.Add(p_IdSr)
Dim p_Item As New System.Data.OracleClient.OracleParameter("p_Item", System.Data.OracleClient.OracleType.NVarChar)
p_Item.Direction = ParameterDirection.Input
p_Item.Value = pItem
cmd.Parameters.Add(p_Item)
Dim p_Text As New System.Data.OracleClient.OracleParameter("p_Text", System.Data.OracleClient.OracleType.NVarChar)
p_Text.Direction = ParameterDirection.Input
p_Text.Value = pText
cmd.Parameters.Add(p_Text)
Dim p_CommonSender As New System.Data.OracleClient.OracleParameter("p_CommonSender", System.Data.OracleClient.OracleType.NVarChar)
p_CommonSender.Direction = ParameterDirection.Input
p_CommonSender.Value = pCommonSender
cmd.Parameters.Add(p_CommonSender)
Dim p_PecSender As New System.Data.OracleClient.OracleParameter("p_PecSender", System.Data.OracleClient.OracleType.NVarChar)
p_PecSender.Direction = ParameterDirection.Input
p_PecSender.Value = pPecSender
cmd.Parameters.Add(p_PecSender)
Dim p_Destination As New System.Data.OracleClient.OracleParameter("p_Destination", System.Data.OracleClient.OracleType.NVarChar)
p_Destination.Direction = ParameterDirection.Input
p_Destination.Value = pDestination
cmd.Parameters.Add(p_Destination)
Dim p_PdfComunication As New System.Data.OracleClient.OracleParameter("p_PdfComunication", System.Data.OracleClient.OracleType.Blob)
p_PdfComunication.Direction = ParameterDirection.InputOutput
p_PdfComunication.Value = pPdfComunication
cmd.Parameters.Add(p_PdfComunication)
cmd.ExecuteNonQuery()
Finally
dbConn.Dispose()
cmd.Dispose()
End Try
'
The problem is that the file size is too big for the blob in the db, which is strange since in other parts of the program that don't do the conversion it takes files way bigger than the ones i'm trying right now...
Any suggestions?
'EDIT
TYPE t_Cursor IS REF CURSOR;
PROCEDURE GetMailTemplate(Cur_Out OUT t_Cursor);
PROCEDURE 1(p_IdComunicationType IN NUMBER,
p_AwaitingStatus IN NUMBER,
p_RequestingUser IN VARCHAR2,
p_IdSr IN VARCHAR2,
p_Item IN VARCHAR2,
p_Testo IN VARCHAR2,
p_CommonSender IN VARCHAR2,
p_PecSender IN VARCHAR2,
p_Destination IN VARCHAR2,
p_PdfComunication xx.PDF_COMUNICATION%Type
);
PROCEDURE 2( p_AwaytingStatus NUMBER, Cur_Out OUT t_Cursor);
PROCEDURE 3(p_IdComunicationType VARCHAR2,
p_AwaitingStatus NUMBER);
We finally found an answer, we had to put everything inside a TRANSACTION:
Public Function InsertComunications(ByVal pIdComunicationType As Integer, ByVal pAwaitingStatus As Integer, ByVal pRequestingUser As String, ByVal pIdSr As String,
ByVal pItem As String, ByVal pText As String, ByVal pCommonSender As String, pPecSender As String, ByVal pDestination As String,
ByVal pPdfComunication As Byte()) As String
Dim dbConn As New OracleConnection
**Dim trns as System.Data.OracleClient.OracleTransaction = Nothing**
Dim cmd As New OracleCommand
Dim errMsg As String = String.Empty
dbConn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings("DBConn").ToString
Try
dbConn.Open()
**trns = dbConn.BeginTransaction**
**cmd.Transaction = trns**
cmd.Parameters.Clear()
cmd.CommandText = ""
cmd.CommandType = System.Data.CommandType.StoredProcedure
cmd.Connection = dbConn
Dim p_IdComunicationType As New System.Data.OracleClient.OracleParameter("p_IdComunicationType ", System.Data.OracleClient.OracleType.Number)
p_IdComunicationType.Direction = ParameterDirection.Input
p_IdComunicationType.Value = pIdComunicationType
cmd.Parameters.Add(p_IdComunicationType)
Dim p_AwaitingStatus As New System.Data.OracleClient.OracleParameter("p_AwaitingStatus", System.Data.OracleClient.OracleType.Number)
p_AwaitingStatus.Direction = ParameterDirection.Input
p_AwaitingStatus.Value = pAwaitingStatus
cmd.Parameters.Add(p_AwaitingStatus)
Dim p_RequestingUser As New System.Data.OracleClient.OracleParameter("p_RequestingUser ", System.Data.OracleClient.OracleType.NVarChar)
p_RequestingUser.Direction = ParameterDirection.Input
p_RequestingUser.Value = pRequestingUser
cmd.Parameters.Add(p_RequestingUser)
Dim p_IdSr As New System.Data.OracleClient.OracleParameter("p_IdSr", System.Data.OracleClient.OracleType.NVarChar)
p_IdSr.Direction = ParameterDirection.Input
p_IdSr.Value = pIdSr
cmd.Parameters.Add(p_IdSr)
Dim p_Item As New System.Data.OracleClient.OracleParameter("p_Item", System.Data.OracleClient.OracleType.NVarChar)
p_Item.Direction = ParameterDirection.Input
p_Item.Value = pItem
cmd.Parameters.Add(p_Item)
Dim p_Text As New System.Data.OracleClient.OracleParameter("p_Text", System.Data.OracleClient.OracleType.NVarChar)
p_Text.Direction = ParameterDirection.Input
p_Text.Value = pText
cmd.Parameters.Add(p_Text)
Dim p_CommonSender As New System.Data.OracleClient.OracleParameter("p_CommonSender", System.Data.OracleClient.OracleType.NVarChar)
p_CommonSender.Direction = ParameterDirection.Input
p_CommonSender.Value = pCommonSender
cmd.Parameters.Add(p_CommonSender)
Dim p_PecSender As New System.Data.OracleClient.OracleParameter("p_PecSender", System.Data.OracleClient.OracleType.NVarChar)
p_PecSender.Direction = ParameterDirection.Input
p_PecSender.Value = pPecSender
cmd.Parameters.Add(p_PecSender)
Dim p_Destination As New System.Data.OracleClient.OracleParameter("p_Destination", System.Data.OracleClient.OracleType.NVarChar)
p_Destination.Direction = ParameterDirection.Input
p_Destination.Value = pDestination
cmd.Parameters.Add(p_Destination)
Dim p_PdfComunication As New System.Data.OracleClient.OracleParameter("p_PdfComunication", System.Data.OracleClient.OracleType.Blob)
p_PdfComunication.Direction = ParameterDirection.InputOutput
p_PdfComunication.Value = pPdfComunication
cmd.Parameters.Add(p_PdfComunication)
cmd.ExecuteNonQuery()
**trns.Commit()**
Finally
dbConn.Dispose()
cmd.Dispose()
End Try

LinkButton in GridView does not fire RowCommand

I am dynamically building a datatable and binding it to a gridview in a VB codebehind. I transform the gridview cell data into LinkButton controls to allow that data to be clicked for updates.
I am using AjaxControlToolkit to present a modal popup to collect data updates. Once those updates are completed, I rebuild the datatable and databind the gridview. In Gridview.RowCreated, I repeat the creation of the LinkButton controls on postback.
When the page is presented following an update, when I click on a LinkButton the postback happens but RowCommand is not fired. While debugging, I notice that when this occurs, Page.FindControl() cannot locate the targeted LinkButton control.
The page is returned without firing the RowCommand event to trigger the display of the modal popup. If I simply press the LinkButton a second time, the LinkButton control can be found using Page.FindControl() and RowCommand fires as desired.
What am I missing? Thanks much for any ideas to resolve this issue. I have struggled with this all day and I'm running out of ideas.
Thank you!
Here is requested code:
<asp:GridView ID="CustomeGridview" GridLines="Vertical" Width="100%" runat="server"
BackColor="White" BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px"
CellPadding="3" AutoGenerateColumns="true" ForeColor="Black" ShowHeader="False" Font-Names="Verdana"
Font-Size="11px" OnRowCommand="CustomeGridview_RowCommand"
OnRowDataBound="CustomeGridview_RowDataBound">
<FooterStyle BackColor="#CCCCCC" />
<SelectedRowStyle BackColor="#000099" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<HeaderStyle BackColor="Black" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="#CCCCCC" />
</asp:GridView>
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Response.CacheControl = "no-cache"
Response.Expires = -1
Response.AddHeader("Pragma", "no-cache")
If Page.IsPostBack = False Then
ViewState("Left") = 3
ViewState("Right") = 6
generateManualDt()
Else
Dim controlName As String = Request.Params.Get("__EVENTTARGET")
Dim ctl As Control = Page.FindControl(controlName)
End If
Page_Header_Label.Text = "Action Qualification Matrix - " & Session("CurrentServiceName")
FormatColumns()
End Sub
Public Sub generateManualDt()
Dim ManualDt As DataTable = BuildMainDataTable()
ViewState("ManualDt") = ManualDt
CustomeGridview.DataSource = ManualDt
CustomeGridview.DataBind()
SetJumpScrollButtons()
End Sub
Protected Sub CustomeGridview_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles CustomeGridview.RowDataBound
Dim dt As DataTable = DirectCast(ViewState("ManualDt"), DataTable)
Dim dtsnocol As DataTable = DirectCast(ViewState("dtsnocol"), DataTable)
If e.Row.RowType = DataControlRowType.DataRow OrElse e.Row.RowType = DataControlRowType.Header Then
For gvCol As Integer = 7 To dt.Columns.Count - 1
e.Row.Cells(gvCol).Visible = False
Next
SetupGridRowControls(e, dtsnocol, dt)
End If
End Sub
Protected Sub CustomeGridview_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles CustomeGridview.RowCreated
Dim dt As DataTable = DirectCast(ViewState("ManualDt"), DataTable)
Dim dtsnocol As DataTable = DirectCast(ViewState("dtsnocol"), DataTable)
e.Row.Cells(0).Visible = False ' Hide the QuestionID column
If Page.IsPostBack Then
If e.Row.RowType = DataControlRowType.DataRow OrElse e.Row.RowType = DataControlRowType.Header Then
SetupGridRowControls(e, dtsnocol, dt)
End If
End If
End Sub
Private Sub SetupGridRowControls(ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs, ByRef dtsnocol As DataTable, ByRef mainDt As DataTable)
Dim CurrSnoCount As Integer = 0
If Not dtsnocol Is Nothing Then
CurrSnoCount = dtsnocol.Rows.Count
End If
If e.Row.DataItemIndex = 0 Then ' Scenario Number row
Dim snoLabel As New Label()
snoLabel.Text = "SCENARIO "
snoLabel.ID = "snoHdrLabel"
e.Row.Cells(2).Controls.Add(snoLabel)
Dim addScenarioBtn = buildAddButton("AddScenario", "", "Click to add a new scenario column")
e.Row.Cells(2).Controls.Add(addScenarioBtn)
ElseIf e.Row.DataItemIndex = 1 Then ' Question Header and Sno Descriptions
Dim questLabel As New Label()
questLabel.Text = "QUESTIONS "
questLabel.ID = "questdrLabel"
e.Row.Cells(2).Controls.Add(questLabel)
Dim addQuestionBtn = buildAddButton("AddQuestion", "", "Click to add a new question row")
e.Row.Cells(2).Controls.Add(addQuestionBtn)
Dim cellText As String = ""
Dim snoId As String = ""
For snoRowIdx As Integer = 0 To CurrSnoCount - 1
snoId = dtsnocol.Rows(snoRowIdx)("ScenarioID").ToString()
cellText = dtsnocol.Rows(snoRowIdx)("Note").ToString()
Dim lnkBtn = buildLinkButton("EditScenario", snoId, cellText)
e.Row.Cells(snoRowIdx + 3).Controls.Add(lnkBtn)
Next
ElseIf e.Row.DataItemIndex > 1 Then ' Question / Responses
Dim cellText As String = ""
Dim cellAddr As String = ""
Dim snoId As String = ""
Dim questId As String = mainDt.Rows(e.Row.DataItemIndex).Item(0).ToString.Trim
For snoRowIdx As Integer = 0 To CurrSnoCount - 1
snoId = dtsnocol.Rows(snoRowIdx)("ScenarioID").ToString.Trim
cellAddr = String.Format("{0}:{1}", questId, snoId)
cellText = mainDt.Rows(e.Row.DataItemIndex).Item(snoRowIdx + 3).ToString.Trim
Dim lnkBtn = buildLinkButton("EditResponses", cellAddr, cellText)
e.Row.Cells(snoRowIdx + 3).Controls.Add(lnkBtn)
Next
End If
End Sub
Private Function buildLinkButton(ByVal linkCmd As String, ByVal linkCmdArg As String, ByVal linkText As String) As LinkButton
Dim lnkBtn As New LinkButton()
lnkBtn.Text = linkText
lnkBtn.CommandName = linkCmd
lnkBtn.CommandArgument = linkCmdArg
lnkBtn.ToolTip = "Click to update"
lnkBtn.CssClass = "cell_link"
Return lnkBtn
End Function
Private Function buildAddButton(ByVal btnCmd As String, ByVal btnCmdArg As String, ByVal btnToolTip As String) As ImageButton
Dim imgBtn As New ImageButton()
imgBtn.CommandName = btnCmd
imgBtn.CommandArgument = btnCmdArg
imgBtn.ImageUrl = "~/Images/services/SmallAddBtn.gif"
imgBtn.ToolTip = btnToolTip
imgBtn.ID = String.Format("{0}_GenImageButton", btnCmd)
Return imgBtn
End Function

MVC3 VB Razor not recognizing converted C# HTML extension method code

I've been looking through Google search results for ways to implement some sort of RadioButton list (VB, MVC3, Razor). Unfortunately, most of the results I find are in C#; this is the most useful reference I can find: Jon Lanceley's MVC3 RadioButton Helper (C#, by the way), so I needed to translate the code into VB (thanks, developerFusion!).
I thought it would be fairly straighforward, but I discovered that the compiler doesn't recognize the function as part of the module namespace; some attempts at working around the problem ensued, but failed.
Here's my code (you can see all the attempts I've tried via comments, signed with Andrew.San if you Ctrl + F it):
Helper:
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.Mvc
Imports System.Web.Mvc.Html
Imports System.Linq.Expressions
Imports System.Runtime.CompilerServices
Imports System.Text
Namespace RadioButtonListForHelperTest
Public Module HtmlExtensions
Sub New()
End Sub
<Extension()> _
Public Function RadioButtonForSelectList(Of TModel, TProperty)( _
htmlHelper As HtmlHelper(Of TModel), _
expression As Expression(Of Func(Of TModel, TProperty)), _
listOfValues As IEnumerable(Of SelectListItem)) As MvcHtmlString
Dim metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData)
Dim stringBuilder = New StringBuilder()
If listOfValues IsNot Nothing Then
' Create a radio button for each item in the list
For Each item As SelectListItem In listOfValues
' Generate an id to be given to the radio button field
Dim id = String.Format("{0}_{1}", metaData.PropertyName, item.Value)
' Create and populate a radio button using the existing html helpers
Dim label = htmlHelper.Label(id, HttpUtility.HtmlEncode(item.Text))
Dim radio = htmlHelper.RadioButtonFor(expression, item.Value, New With { _
Key .id = id _
}).ToHtmlString()
' Create the html string that will be returned to the client
' e.g. <input data-val="true" data-val-required="You must select an option" id="TestRadio_1" name="TestRadio" type="radio" value="1" /><label for="TestRadio_1">Line1</label>
stringBuilder.AppendFormat("<div class="RadioButton">{0}{1}</div>", radio, label)
Next
End If
Return MvcHtmlString.Create(stringBuilder.ToString())
End Function
End Module
End Namespace
Model:
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.ComponentModel.DataAnnotations
Imports System.Web.Mvc
Namespace RadioButtonListForHelperTest.Models
Public Class TestModel
Public Property TestRadioList() As IEnumerable(Of SelectListItem)
Get
Return m_TestRadioList
End Get
Set(value As IEnumerable(Of SelectListItem))
m_TestRadioList = value
End Set
End Property
Private m_TestRadioList As IEnumerable(Of SelectListItem)
Public Property TestRadioList2() As IEnumerable(Of SelectListItem)
Get
Return m_TestRadioList2
End Get
Set(value As IEnumerable(Of SelectListItem))
m_TestRadioList2 = value
End Set
End Property
Private m_TestRadioList2 As IEnumerable(Of SelectListItem)
<Display( _
Name:="Test Radio 1", _
Description:="This is the first list.", _
Prompt:="Some prompt message.", _
Order:=2)> _
<Required(ErrorMessage:="You must select an option for TestRadio")> _
Public Property TestRadio() As String
Get
Return m_TestRadio
End Get
Set(value As String)
m_TestRadio = value
End Set
End Property
Private m_TestRadio As String
<Display( _
Name:="Test Radio 2", _
Description:="This is the second list.", _
Prompt:="Some prompt message.", _
Order:=1)> _
<Required(ErrorMessage:="You must select an option for TestRadio2")> _
Public Property TestRadio2() As String
Get
Return m_TestRadio2
End Get
Set(value As String)
m_TestRadio2 = value
End Set
End Property
Private m_TestRadio2 As String
' I tried it out, just in case
' (see Index; #Html.RadioButtonForSelectList).
' It didn't help, really.
' - Andrew.San
Public Function RadioButtonForSelectList(Of TModel, TProperty)( _
htmlHelper As HtmlHelper(Of TModel), _
expression As Expressions.Expression(Of Func(Of TModel, TProperty)), _
listOfValues As IEnumerable(Of SelectListItem)) As MvcHtmlString
Return RadioButtonListForHelperTest.RadioButtonForSelectList(htmlHelper, expression, listOfValues)
End Function
End Class
Public Class aTest
Public Property ID() As Integer
Get
Return m_ID
End Get
Set(value As Integer)
m_ID = value
End Set
End Property
Private m_ID As Integer
Public Property Name() As String
Get
Return m_Name
End Get
Set(value As String)
m_Name = value
End Set
End Property
Private m_Name As String
End Class
End Namespace
Controller:
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.Mvc
Imports RadioButtonListForHelperTest.RadioButtonListForHelperTest.Models
Namespace Controllers
Public Class TestController
Inherits System.Web.Mvc.Controller
'
' GET: /Test
Function Index() As ActionResult
Dim list As New List(Of aTest)()
list.Add(New aTest() With { _
.ID = 1, _
.Name = "Line1" _
})
list.Add(New aTest() With { _
.ID = 2, _
.Name = "Line2" _
})
list.Add(New aTest() With { _
.ID = 3, _
.Name = "Line3" _
})
Dim sl As New SelectList(list, "ID", "Name")
Dim list2 As New List(Of aTest)()
list2.Add(New aTest() With { _
.ID = 1, _
.Name = "test1" _
})
list2.Add(New aTest() With { _
.ID = 2, _
.Name = "test2" _
})
Dim sl2 As New SelectList(list2, "ID", "Name")
Dim model = New TestModel()
model.TestRadioList = sl
model.TestRadioList2 = sl2
model.TestRadio = "2"
' Set a default value for the first radio button helper
Return View(model)
End Function
'
' POST: /Test
<HttpPost()> _
Public Function Index(model As TestModel, returnUrl As String) As ActionResult
If ModelState.IsValid Then
ModelState.AddModelError("", "Always force an error to be raised so we can test the postback sets the radio buttons to their last values.")
End If
' If we got this far, something failed, redisplay form
Dim list As New List(Of aTest)()
list.Add(New aTest() With { _
.ID = 1, _
.Name = "Line1" _
})
list.Add(New aTest() With { _
.ID = 2, _
.Name = "Line2" _
})
list.Add(New aTest() With { _
.ID = 3, _
.Name = "Line3" _
})
Dim sl As New SelectList(list, "ID", "Name")
Dim list2 As New List(Of aTest)()
list2.Add(New aTest() With { _
.ID = 1, _
.Name = "test1" _
})
list2.Add(New aTest() With { _
.ID = 2, _
.Name = "test2" _
})
Dim sl2 As New SelectList(list2, "ID", "Name")
model.TestRadioList = sl
model.TestRadioList2 = sl2
Return View(model)
End Function
End Class
End Namespace
View:
#Imports RadioButtonListForHelperTest <!-- Andrew.San - Looked up Google on how to import a namespace in VB -->
#ModelType RadioButtonListForHelperTest.RadioButtonListForHelperTest.Models.TestModel
#Code
Dim obj1 As System.Web.Mvc.HtmlHelper(Of RadioButtonListForHelperTest.RadioButtonListForHelperTest.Models.TestModel)
Dim obj2 As System.Web.Mvc.HtmlHelper(Of RadioButtonListForHelperTest.RadioButtonListForHelperTest.Models.TestModel)
ViewData("Title") = "Index"
End Code
<h2>Index</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#Using Html.BeginForm()
#Html.ValidationSummary(True)
#<fieldset>
<legend>TestModel</legend>
<div class="editor-label">
#Html.LabelFor(Function(model) model.TestRadio)
</div>
<div class="editor-field">
#Html.RadioButtonForSelectList(Function(model) model.TestRadio, Model.TestRadioList)
<!-- Andrew.San
Apparently, the method isn't a member of
System.Web.Mvc.HtmlHelper(Of RadioButtonListForHelperTest.RadioButtonListForHelperTest.Models.TestModel),
which is odd; I don't see the need for a Model to have this method.
-->
#RadioButtonListForHelperTest.RadioButtonListForHelperTest.RadioButtonForSelectList(obj1, Function(model) model.TestRadio, Model.TestRadioList)
<!-- Andrew.San
The compiler needs me to send an htmlHelper argument to the
HtmlExtension RadioButtonForSelectList method,
which Jon Lanceley didn't need to do.
#Html.RadioButtonForSelectList(m => m.TestRadio, Model.TestRadioList)
-->
#Html.ValidationMessageFor(Function(model) model.TestRadio)
</div>
<div class="editor-label">
#Html.LabelFor(Function(model) model.TestRadio2)
</div>
<div class="editor-field">
<!-- Andrew.San
As per the first radio button list.
-->
#Html.RadioButtonForSelectList(Function(model) model.TestRadio2, Model.TestRadioList2)
#RadioButtonListForHelperTest.RadioButtonListForHelperTest.RadioButtonForSelectList(obj2, Function(model) model.TestRadio2, Model.TestRadioList2)
#Html.ValidationMessageFor(Function(model) model.TestRadio2)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
End Using
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Right. That's all I've got.
The problem is that your extension method is in the RadioButtonListForHelperTest namespace, but in your view you attempt to access it view the System.Web.Mvc.Html namespace. #Html is in System.Web.Mvc.
To access your extension method in the same namespace you need to do the following.
Change your current namespace to System.Web.Mvc.Html. Then create a static class named whatever you like, MyExtensions and then include you extension method in this class. It must be static.

custom htmlhelper with validation support

I'm rockin my own custom HtmlHelper to enable AutoComplete support on a Select List.
This is working alright, except I need to be able to support the DataAnnotations in my ViewModel.
Here's my current (working) HtmlHelper (sans validation)
<Extension()>
Public Function AutoCompleteDropDownList(ByVal helper As HtmlHelper, name As String, autoCompleteSelectListItem As List(Of AutoCompleteSelectListItem), htmlAttributes As Object) As MvcHtmlString
Dim selectBuilder As New TagBuilder("select")
selectBuilder.MergeAttribute("name", name)
selectBuilder.MergeAttributes(New RouteValueDictionary(htmlAttributes))
selectBuilder.MergeAttribute("autocorrect", "off")
selectBuilder.MergeAttribute("autocomplete", "off")
Dim selectListBuilder As New TagBuilder("option")
selectListBuilder.MergeAttribute("value", "")
selectListBuilder.MergeAttribute("selected", "selected")
Dim innerHtmlBuilder As New StringBuilder
innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
For Each item In autoCompleteSelectListItem
selectListBuilder = New TagBuilder("option")
selectListBuilder.MergeAttribute("value", item.Value)
selectListBuilder.MergeAttribute("data-alternative-spellings", item.AlternativeSpellings)
selectListBuilder.MergeAttribute("data-relevancy-booster", item.RelevancyBooster)
selectListBuilder.InnerHtml = item.Label
innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
Next
selectBuilder.InnerHtml = innerHtmlBuilder.ToString()
Return MvcHtmlString.Create(selectBuilder.ToString(TagRenderMode.Normal))
End Function
How would one rewrite this to support validation? Something like AutoCompleteDropDownListFor()
PS: a C# solution is perfectly acceptable, the project I'm working on is in VB, but I don't mind translating.
PS: I'm flipping through the source code on http://aspnet.codeplex.com and I can't find any reference to DropDownListFor
You will have to download the source code and you will find the implementation of the DropDownListFor helper inside mvc3-rtm-sources.zip\mvc3-rtm-sources\mvc3\src\SystemWebMvc\Mvc\Html\SelectExtensions.cs. To enable client side validation you have to emit HTML5 data-* attributes on the drop down. This is done towards the end of the SelectInternal method by calling htmlHelper.GetUnobtrusiveValidationAttributes method.
<Extension()>
Public Function AutoCompleteDropDownList(ByVal helper As HtmlHelper, name As String, autoCompleteSelectListItem As List(Of AutoCompleteSelectListItem), htmlAttributes As Object) As MvcHtmlString
Dim selectBuilder As New TagBuilder("select")
selectBuilder.MergeAttribute("name", name)
selectBuilder.MergeAttributes(New RouteValueDictionary(htmlAttributes))
selectBuilder.MergeAttribute("autocorrect", "off")
selectBuilder.MergeAttribute("autocomplete", "off")
Dim selectListBuilder As New TagBuilder("option")
selectListBuilder.MergeAttribute("value", "")
selectListBuilder.MergeAttribute("selected", "selected")
Dim innerHtmlBuilder As New StringBuilder
innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
For Each item In autoCompleteSelectListItem
selectListBuilder = New TagBuilder("option")
selectListBuilder.MergeAttribute("value", item.Value)
selectListBuilder.MergeAttribute("data-alternative-spellings", item.AlternativeSpellings)
selectListBuilder.MergeAttribute("data-relevancy-booster", item.RelevancyBooster)
selectListBuilder.InnerHtml = item.Label
innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
Next
selectBuilder.InnerHtml = innerHtmlBuilder.ToString()
selectBuilder.MergeAttributes(helper.GetUnobtrusiveValidationAttributes(name))
Return MvcHtmlString.Create(selectBuilder.ToString(TagRenderMode.Normal))
End Function
UPDATE:
As requested in the comments section, here's how a strongly typed version of the helper would look like:
<Extension()>
Public Function AutoCompleteDropDownListFor(Of TModel, TProperty)(helper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TProperty)), autoCompleteSelectListItem As List(Of AutoCompleteSelectListItem), htmlAttributes As Object) As IHtmlString
Dim name = ExpressionHelper.GetExpressionText(expression)
Dim fullHtmlFieldName As String = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name)
Dim selectBuilder = New TagBuilder("select")
selectBuilder.MergeAttribute("name", fullHtmlFieldName)
selectBuilder.MergeAttributes(New RouteValueDictionary(htmlAttributes))
selectBuilder.MergeAttribute("autocorrect", "off")
selectBuilder.MergeAttribute("autocomplete", "off")
Dim selectListBuilder = New TagBuilder("option")
selectListBuilder.MergeAttribute("value", "")
selectListBuilder.MergeAttribute("selected", "selected")
Dim innerHtmlBuilder = New StringBuilder()
innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
For Each item In autoCompleteSelectListItem
selectListBuilder = New TagBuilder("option")
selectListBuilder.MergeAttribute("value", item.Value)
selectListBuilder.MergeAttribute("data-alternative-spellings", item.AlternativeSpellings)
selectListBuilder.MergeAttribute("data-relevancy-booster", item.RelevancyBooster)
selectListBuilder.InnerHtml = item.Label
innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
Next
selectBuilder.InnerHtml = innerHtmlBuilder.ToString()
selectBuilder.MergeAttributes(helper.GetUnobtrusiveValidationAttributes(name))
Return MvcHtmlString.Create(selectBuilder.ToString(TagRenderMode.Normal))
End Function

How do I rebind a combobox in winforms?

I have a Winforms application and a combobox has it's datasource set to a DataTable when the form loads. The data displays fine in the combobox.
Then after a user clicks a button I want to create a new DataTable and assign that datatable as the datasource for the combobox.
The problem is that after setting the datasource to be the new datatable the items in the combobox don't change. Here is the code I'm using.
dlCustomer.DataSource = Nothing
dlCustomer.DataSource = dtCustomers
dlCustomer.DisplayMember = "Name"
dlCustomer.Refresh()
Does anyone know how to make the correct data be displayed in the combobox the second time I assign the data source for it?
It should work, at least it did in a quick test I threw together. Here's the code; it just expects a Form with a ComboBox and Button:
Public Class Form1
Private dtOne As DataTable
Private dtTwo As DataTable
Private Sub InitializeTables()
dtOne = New DataTable("TableOne")
With dtOne
.Columns.Add("Text", GetType(String))
.Columns.Add("Value", GetType(Integer))
End With
dtTwo = New DataTable("TableTwo")
With dtTwo
.Columns.Add("Text", GetType(String))
.Columns.Add("Value", GetType(Integer))
End With
Dim newRow As DataRow
For index As Integer = 0 To 2
newRow = dtOne.NewRow
newRow.ItemArray = (New Object() {SpellIt(index), index})
dtOne.Rows.Add(newRow)
Next
For index As Integer = 2 To 0 Step -1
newRow = dtTwo.NewRow
newRow.ItemArray = (New Object() {SpellIt(index), index})
dtTwo.Rows.Add(newRow)
Next
dtOne.AcceptChanges()
dtTwo.AcceptChanges()
End Sub
Private Shared Function SpellIt(ByVal int As Integer) As String
Select Case int
Case 0 : Return "Zero"
Case 1 : Return "One"
Case 2 : Return "Two"
Case Else : Throw New ArgumentOutOfRangeException("Bleh!")
End Select
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
InitializeTables()
Me.Label1.DataBindings.Add("Text", ComboBox1, "SelectedValue")
Me.ComboBox1.DataSource = dtOne
Me.ComboBox1.DisplayMember = "Text"
Me.ComboBox1.ValueMember = "Value"
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.ComboBox1.DataBindings.Clear()
Me.ComboBox1.DataSource = Nothing
Me.ComboBox1.DataSource = dtTwo
Me.ComboBox1.DisplayMember = "Text"
Me.ComboBox1.ValueMember = "Value"
End Sub
End Class

Resources