1

My RadioButtonList :

<asp:RadioButtonList ID="rblType" runat="server" selectedvalue='<%#Bind("Type")%>' AutoPostBack="true" >
         <asp:ListItem Text="X" Value="X" />
         <asp:ListItem Text="E" Value="E" />
         <asp:ListItem Text="H" Value="H" />
         <asp:ListItem Text="F" Value="F" />
         <asp:ListItem Text="A" Value="A" />
</asp:RadioButtonList>

It is inside a formview:

<asp:FormView ID="fv" runat="server" DataSourceID="ds" DataKeyNames="ChartId,Type,ItemId"
    OnModeChanged="fv_ModeChanged">

Datasource :

<asp:EntityDataSource ID="ds" runat="server" 
    ContextTypeName="Model.Entities"
    EntitySetName="ItemCharts" EnableInsert="true" EnableUpdate="true" AutoGenerateWhereClause="true"
    OnInserting="ds_Inserting" >
    <WhereParameters>
        <asp:QueryStringParameter Name="ItemId" DbType="Int32" QueryStringField="id" />
        <asp:QueryStringParameter Name="ChartId" DbType="Int32" QueryStringField="chart" />
        <asp:QueryStringParameter Name="Type" DbType="String" QueryStringField="type" />
    </WhereParameters>
</asp:EntityDataSource>

Error message :

has a SelectedValue which is invalid because it does not exist in the list of items

Cause :

The value I get from Bind() is a lower case 'x', the value of the ListItem is upper case 'X'.

I have lower case 'x' and upper case 'X' in my database.

I'm trying to find a way to keep the 'Bind' functionnalities, and select a listItem ignoring case sensitivity.

Any suggestions?

Thank you!

JoRouss
  • 2,864
  • 2
  • 22
  • 40

4 Answers4

1

The Bind expression can be used with a custom format, but in .Net there is no way to instruct the format to "lowercase" or "uppercase" the object, so you need to build a custom format provider. I don't know how "inject" such a provider to the Bind expression or if even it's possible (or if it worths the effort).

Since you are using EF, you can benefit on the partial methods used when a property is changed so you can write code to always save the Type in Uppercase.

  partial void OnTypeChanged()
        {
           if (this._Type != null)
             this._Type = this._Type.ToUpper();
        }
Community
  • 1
  • 1
Adrian Iftode
  • 15,465
  • 4
  • 48
  • 73
  • 1
    Yeah I did read about the custom format too, and didn't find a way to format ToUpper. Every insert/update is now made with radiobuttonlist wich contains upper case values. I'll have to test your solution one day! Thanks for your help! – JoRouss Mar 28 '12 at 12:09
0

Since I did not want to perform manual binding for every dropdown that I needed to behave as non-case-sensitive, I decided to create a custom control that inherits DropDownList. They all I need to do is mark it in the designed as CaseInsensitive=True.

Here is the code for the new controls:

Imports System
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace CSControls.Web
<DefaultProperty("SelectedValue"), ToolboxData("<{0}:CSDropDownList runat=server>/{0}:CSDropDownList>")> Public Class CSDropDownList
Inherits DropDownList

Private _RawSelectedValue As String

<Bindable(True), Category("Data"), Localizable(True)> Overrides Property SelectedValue() As String
  Get
    Return MyBase.SelectedValue
  End Get

  Set(ByVal Value As String)
    _RawSelectedValue = Value
    FixCaseSensitivity(False)
  End Set
End Property

Private Sub FixCaseSensitivity(ForceValue As Boolean)
  If CaseInsensitive Then
    If Not Creditsoft.IsNothingNullOrEmpty(_RawSelectedValue) Then
      If IsNothing(Me.Items.FindByValue(_RawSelectedValue)) Then
        For Each item As ListItem In Me.Items
          If item.Value.ToUpper() = _RawSelectedValue.ToUpper() Then
            MyBase.SelectedValue = item.Value
            Exit Sub 'New Selected Value was found so we can stop looping
          End If
        Next
        If ForceValue Then 'ForceValue is TRUE when called from the OnDataBound. So in this case we need to let the application throw an exception because it's probably a programming error
          MyBase.SelectedValue = _RawSelectedValue
        End If
      Else
        MyBase.SelectedValue = _RawSelectedValue
      End If
    Else
      MyBase.SelectedValue = Nothing
    End If
  Else
    MyBase.SelectedValue = _RawSelectedValue
  End If
End Sub

Protected Overrides Sub OnDataBinding(e As System.EventArgs)
  MyBase.OnDataBinding(e)
End Sub

Protected Overrides Sub OnDataBound(e As System.EventArgs)
  MyBase.OnDataBound(e)
  FixCaseSensitivity(True)
End Sub

Private _CaseInsensitive As Boolean = False
<Category("Data"), DefaultValue("False")> Public Property CaseInsensitive As Boolean
  Get
    If IsNothing(ViewState("CaseInsensitive")) Then
      Return _CaseInsensitive
    Else
      Return ViewState("CaseInsensitive")
    End If
  End Get
  Set(value As Boolean)
    ViewState("CaseInsensitive") = value
    _CaseInsensitive = value
  End Set
End Property
End Class

End Namespace

Then You can use it in your aspx page or ascx control as follows:

<%@ Register Namespace="CSControls.Web" TagPrefix="CSControlsWeb" %>

<CSControlsWeb:CSDropDownList id="ddlStates" runat="server" width="58px" 
    SelectedValue='<%# Bind("State") %>' AppendDataBoundItems="True" 
    DataSourceID="StatesDataSource" DataTextField="State" 
    DataValueField="State" CssClass="BoxEditable" CaseInsensitive="True" >
    <asp:ListItem Value="">State</asp:ListItem>
</CSControlsWeb:CSDropDownList>
0

I ran a script to make every 'Type' to upper case in the database. Now I make sure datas are saved as upper case on insertion/edition.

Let me know if you find a way to use Bind with formatting.

JoRouss
  • 2,864
  • 2
  • 22
  • 40
-1

Sample HTML

<asp:RadioButtonList ID="ed" runat="server" selectedvalue=<%#ConvertToUpper(Eval("abc"))%> >
     <asp:ListItem Text="A" Value="A"></asp:ListItem>
</asp:RadioButtonList>

public static string ConvertToUpper(object value)
{
    return value.ToString().ToUpper();
}

You can alternatively modify the DataTable in your FormView

protected void FormView_DataBound(object sender, EventArgs e)
{
    DataTable Dt = ((System.Data.DataRowView)FormView.DataItem).DataView.ToTable();
    foreach (DataRow Dr in Dt.Rows)
    {
        Dr["abc"] = Dr["abc"].ToString().ToUpper();
    }
}

My testing Data

using (DataTable dt = new DataTable())
{
    using (DataColumn dc = new DataColumn("abc"))
    {
        dt.Columns.Add(dc);

        DataRow dr = dt.NewRow();
        dr["abc"] = "A";
        dt.Rows.Add(dr);

        dr = dt.NewRow();
        dr["abc"] = "b";
        dt.Rows.Add(dr);
    }
}
Pankaj
  • 9,749
  • 32
  • 139
  • 283
  • What this has to do with the Bind function? – Adrian Iftode Mar 27 '12 at 15:03
  • That's not really what I need – JoRouss Mar 27 '12 at 15:04
  • I assume you have Bind function definition in your code behind. IN your bind function, you can validate the data before binding to control and finally assign the converted to upper value. – Pankaj Mar 27 '12 at 15:18
  • Because: "I assume you have Bind function definition in your code behind." see this link http://msdn.microsoft.com/en-us/library/ms178366.aspx – Adrian Iftode Mar 27 '12 at 15:27
  • 1
    If you find a solution how to use Bind with formatting I'll remove my downvote – Adrian Iftode Mar 27 '12 at 15:28
  • You lose the 2 way Binding functionnalities by doing this – JoRouss Mar 27 '12 at 16:00
  • @PankajGarg, still it doesn't suffice, sorry. There is another much simpler way to write your solution: SelectedValue='<%# ((string)Eval("abc")).ToUpper()%>'. However, when an update is made this doesn't work (@JoRouss needs to use the Bind function to update the Type also) – Adrian Iftode Mar 28 '12 at 05:07