views:

1614

answers:

1

Hi,

I have a DataList displayed on a (Asp.Net3.5) page which the user can select from. The datakey value of the selected row is then stored in the database.

If the page should be revisited by the same user at some point in the future the selected datakey value is retreived from the DB. I would like to use this datakey value to highlight the corresponding row in the DataList.

How can i set the appropriate SelectedIndex of the DataList from this DataKey value?

I have tried the following;

      protected void dlCampChars_DataBinding(object sender, EventArgs e)
 {
  for (int i = 0; i < dlCampChars.Items.Count; i++)
{
    // Ignore values that cannot be cast as integer.
    try
    {
        if (dlCampChars.DataKeys[i].ToString() == lSelection.ToString())
        {
            Label28.Text = i + "";
            dlCampChars.SelectedIndex = i + 1;
        }

    }
    catch { }
  }
}

If i set it in ItemDataBinding the SelectedIndex update is made after the DL has been bound and has no effect. Any ideas??

Thanks

UPDATED CODE

                    // if stored DataKey exists loop through DataTable
                // looking for the index of the item matching the DataKey
                int itemIndex = 0;
                for (int i = 0; i < dt.Rows.Count; i++)
                 {
                  // check the appropriate "DataKey" column name of the current row
                  if (dt.Rows[i]["cha_Key"].ToString() == lSelection)
                  {
                  // match found, set index and break out of loop
                  itemIndex = i;
                  break;
                  }
                 }
+2  A: 

It seems things are a little backwards in DataList land, depending on when the item is rendered and which template it is in (check out the 1st link below for an explanation). The ItemDataBound approach is valid, but sometimes is a little quirky as described in that article. In the case you describe I believe the 2nd approach would work, where you can set the SelectedIndex property prior to the call to DataBind(). The steps are:

  1. Provided PostBack is false
  2. Set the SelectedIndex
  3. Set the DataSource
  4. DataBind

Here's an example:

  void Page_Load(Object sender, EventArgs e) 
  {
     // Load sample data only once, when the page is first loaded.
     if (!IsPostBack) 
     {
       dlCampChars.DataSource = CreateDataSource();
       dlCampChars.DataBind();
     }
  }

private DataTable CreateDataSource()
{
  // however you get your data and whatever the resulting object is
  // for example: DataTable, DataView, etc.
  DataTable dt = [relevant code here];

  // retrieve the user's stored DataKey
  string datakey = [retrieved datakey value from DB];

  // if stored DataKey exists loop through DataTable
  // looking for the index of the item matching the DataKey
  int itemIndex = 0;
  for (int i = 0; i < dt.Rows.Count; i++)
  {
    // check the appropriate "DataKey" column name of the current row
    if (dt.Rows[i]["DataKey"].ToString() == datakey)
    {
      // match found, set index and break out of loop
      itemIndex = i;
      break;
    }
  }

  // set SelectedIndex
  dlCampChars.SelectedIndex = itemIndex;

  // now return the DataSource (ie. DataTable etc.)
  return dt;
}

You might find these articles helpful:

EDIT: added DataTable for loop code. The idea would be the same for whatever your actual datasource object is.

Ahmad Mageed
Great stuff. Sorry to be a pain but i cant think straight anymore. What do i need to do for the 'var itemIndex = [index of above item];' bit?
Munklefish
You would loop through your DataTable or whatever your DataSource object is. For example use a for loop and match the current DataTable row/column item with the stored DataKey. If it matches, then the itemIndex would be the current for loop index number. I'll try to edit and add an example.
Ahmad Mageed
That would be great thanks.
Munklefish
Updated with the datakey variable and for loop example. The idea is the same be it a DataTable, DataView, List etc.
Ahmad Mageed
Ahmad, thanks for that. Ive updated my question to reflect how ive dapted your code. However i am getting an error in VWE2008 with the red squiggle un the '(dt.Rows.["cha_Key"]' bit. It says the overload method for DataDataRowCollection.this[int] has invalid arguments.Any ideas?
Munklefish
+1 - Your answer was correct so I upvoted you and deleted mine. I wouldn't my answer providing a "gotcha" for anyone else.
CAbbott
@Munklefish: try using dt.Rows["cha_Key"] instead of dt.Rows.["cha_Key"] (notice there is no dot between Rows and ["cha_Key"])
Ahmad Mageed
Ahmad, that was just a typo. It actually needed the int value adding to reference the row eg: dt.Rows[i]["cha_Key"]All works fine now THANKS!!!!!
Munklefish
@CAbbott: thanks. Like I said in my opening paragraph that approach isn't necessarily wrong (most of the other controls follow that pattern) and the article explains those 2 scenarios nicely.
Ahmad Mageed
@Munklefish: ah, good catch. I'll update my code to reflect that. Glad you got it working!
Ahmad Mageed