Bunch's Blog

  Home  |   Contact  |   Syndication    |   Login
  48 Posts | 0 Stories | 36 Comments | 0 Trackbacks

News

Tag Cloud


Archives

Green

This post deals with 2-way binding of data to a CascadingDropDown. It assumes that the CascadingDropDown is already configured to return data to the list.
 
I had my DropDownList and CascadingDropDown pairs within a FormView and it is bound to a SqlDataSource.
 
<asp:Label ID="Label1" runat="server" Text="Mfr" />
 
<asp:DropDownList ID="ddlMfrs" runat="server" />
 
<cc1:CascadingDropDown ID="cddMfr" runat="server" TargetControlID="ddlMfrs" Category="MfrID" PromptText="Select a manufacturer" ServicePath="MfrService.asmx" ServiceMethod="GetMfrs" ContextKey="M" SelectedValue='<%# BIND("MfrID") %>'>
</cc1:CascadingDropDown>
 
When the data is being bound (i.e. Selecting) there is no problem. If the MfrID value is a 3 then it selects the item from the drop down list with a 3 like it should. The issue occurred when the data was being updated back to the database. The error I received was that the input was not in the correct format.
 
When I checked the NewValues of MfrID in FormView ItemUpdating I saw that the value wasn’t a 3 but rather 3:::MfrName. The error makes sense now since the sproc was looking for an integer for its MfrID parameter.
 
Since this was my only page using the CascadingDropDown I dealt with the error on in its code behind. I added the following to the FormView’s ItemUpdating:
 
Protected Sub fv1_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles fv1.ItemUpdating
        Dim strTemp As String
        Dim strKey As String
        For Each strKey In e.NewValues.Keys
            strTemp = e.NewValues(strKey).ToString
            If strTemp.Contains(":::") Then
                e.NewValues(strKey) = CleanBindValue(strTemp)
            End If
        Next
End Sub
 
And this is the CleanBindValue function that gets called:
 
Private Function CleanBindValue(ByVal DirtyValue As String) As String
        'CascadingDropDown returns BIND values as value:::text
        'and needs to be cleaned prior to database update
        Dim strSplit() As String
        strSplit = DirtyValue.Split(":::")
        Return strSplit(0).ToString
End Function
 
Now the CleanBindValue function returns just the integer and the updates proceeds normally.

C# Code for the above two functions:

protected void FormView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)

    {

        string strTemp;

        foreach (string strKey in e.NewValues.Keys)

        {
            strTemp = (string)e.NewValues[strKey];

            if (strTemp.Contains(":::"))

            {

                e.NewValues[strKey] = CleanBindValue(strTemp);

            }
        }
    }
 

    private string CleanBindValue(string DirtyValue)

    {

        string[] strSplit;

        string strDelimiter = ":::";

        char[] chDelimiter = strDelimiter.ToCharArray();

        strSplit = DirtyValue.Split(chDelimiter);

        return strSplit[0];

    }
 

Technorati Tags: ,,
posted on Wednesday, October 01, 2008 9:08 AM

Feedback

# re: 2-Way Binding with CascadingDropDown 11/27/2008 12:47 PM Javier
Do you have the code in C# I get a bit anoyed sometimes with VB.

Thanks,

Javier


# re: 2-Way Binding with CascadingDropDown 2/7/2009 9:36 AM HUSSEIN
THANKS

SAVED ME A LOT OF TROUBLE


# re: 2-Way Binding with CascadingDropDown 8/25/2009 7:48 AM Lennox McKenzie
It's quirky, but this saved my butt. The only issue I had was a boolean value in my EditTemplate.

protected void DetailsView1_ItemUpdating(object sender, DetailsViewUpdateEventArgs e) {
var strTemp = string.Empty;

foreach (var strKey in e.NewValues.Keys) {
if (!(e.NewValues[strKey] is string))
//skip anything we can't cast to a string
continue;

strTemp = (string)e.NewValues[strKey];

if (strTemp.Contains(":::"))
e.NewValues[strKey] = cleanBindValue(strTemp);
}
}

private object cleanBindValue(string DirtyValue) {
var delim = ":::".ToCharArray();

return DirtyValue.Split(delim)[0];
}

# re: 2-Way Binding with CascadingDropDown 9/4/2009 6:54 AM Agony
I realize this is kinda old, but I had to thank you for this. Saved me ton of headache!!!!! Thank you, thank you, thank you. I ended up creating a custom control inheriting from CascadingDropDown and adding a bindable property, clean up the selected value there and setting the property on load.

using System;
using System.ComponentModel;
using System.Web.UI;
using AjaxControlToolkit;

namespace CustomServerControls {
[ToolboxData("<{0}:SmartCascadingDropDown runat=server></{0}:smartCascadingDropDown>")]
public class SmartCascadingDropDown : CascadingDropDown {

private char[] _seperator = ":::".ToCharArray();

private string _DropDownSelectedValue;

[Bindable(BindableSupport.Yes)]
[Category("Data")]
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
public string DropDownSelectedValue {
get {
return _DropDownSelectedValue;
}
set {
_DropDownSelectedValue = value;
}
}

protected override void OnLoad(EventArgs e) {
base.OnLoad(e);

_DropDownSelectedValue = cleanUpValue(base.SelectedValue);
}

private string cleanUpValue(string inputString) {
var outputString = inputString.Split(_seperator)[0];

return outputString;
}
}
}




# re: 2-Way Binding with CascadingDropDown 9/4/2009 7:01 AM Agony
Forgot to add, set properties for control as:

SelectedValue='<%# Eval("FieldID") >'
DropDownSelectedValue='<%# Bind("FieldID") %>'

I'm sure I could have overriden SelectedValue, but I prefer not to risk breaking any existing functionality so I can use the derived CascadingDropDown like a normal one if I need to.

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: