Results 1 to 6 of 6

Thread: Dynamic UserControl with DropDownLists - not remembering selected values

Threaded View

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Dynamic UserControl with DropDownLists - not remembering selected values

    Hi,

    I have a UserControl that contains a number of DropDownList controls. One instance of this control represents a list of favorites of a game for one particular user (favorite weapon, map, gametype, etc).
    There's actually two versions: there's also one that just displays the values (with labels instead of dropdowns).

    The website is about an entire branch of games, including past and future games, and in each game the favorite weapon, map, gametype, etc, applies, so I came up with the following design.

    The profile page for each user should display their favorites for each game. Since in the future new games will come out, I am loading the games from the database. For each game, I am dynamically adding a TabPanel into a TabContainer control, which I got from the AJAX Toolkit controls.
    In each of these TabPanels, I then dynamically add a new instance of the favorites UserControl that displays the values.

    When I add a game to my database in the future, another TabPanel will automatically show up (albeit with blank values at first) so the user can choose his values for that new game.



    Anyway, I hope the setup is clear... If not, just imagine a TabContainer with a bunch of TabPanels, where each TabPanel contains a UserControl. The UserControl contains a number of DropDownLists that the user uses to choose some values from a database.

    The UserControl has this code:
    csharp Code:
    1. public partial class EditFavoritesControl : System.Web.UI.UserControl
    2.     {
    3.         // Fields to hold ALL weapons and maps (from this particular game)
    4.         // that the user can choose from
    5.         private FlagEntityCollection<Weapon> weapons;
    6.         private FlagEntityCollection<Map> maps;
    7.  
    8.         protected void Page_Load(object sender, EventArgs e)
    9.         {
    10.             if (this.Game == null || this.Favorites == null) return;
    11.  
    12.             // Always load all choices into the private fields above, regardless of postback or not
    13.             this.LoadChoices();
    14.            
    15.            
    16.             if (!this.IsPostBack)
    17.             {
    18.                 // If it's not a postback, load the values into the DropdownLists
    19.                 this.LoadLists();
    20.                
    21.                 // Then select the appropriate values based on what is stored in the database for this user
    22.                 this.LoadSelections();
    23.             }
    24.         }
    25.  
    26.         public ProfileFavorite Favorites { get; set; }
    27.         public Profile Profile { get; set; }
    28.         public Game Game { get; set; }
    29.  
    30.         private void LoadChoices()
    31.         {
    32.             weapons = WeaponManager.Instance.LoadFromGame(this.Game);
    33.             maps = MapManager.Instance.LoadFromGame(this.Game);
    34.         }
    35.  
    36.         private void LoadLists()
    37.         {
    38.             // Weapons and Maps have properties Name and unique Id (int)
    39.             // The dropdowns should display the name but store the Id as the value
    40.            
    41.             cboWeapons.DataSource = weapons;
    42.             cboWeapons.DataTextField = "Name";
    43.             cboWeapons.DataValueField = "Id";
    44.             cboWeapons.DataBind();
    45.                        
    46.             cboMaps.DataSource = maps;
    47.             cboMaps.DataTextField = "Name";
    48.             cboMaps.DataValueField = "Id";
    49.             cboMaps.DataBind();
    50.         }
    51.  
    52.         private void LoadSelections()
    53.         {
    54.             if (this.Favorites == null) return;
    55.  
    56.             // this.Favorites.Weapon, for example, is the weapon that this user has selected previously as his favorite
    57.             cboWeapons.SelectedValue = this.Favorites.Weapon.Id.ToString();
    58.             cboMaps.SelectedValue = this.Favorites.Map.Id.ToString();
    59.         }
    60.  
    61.         public void Save()
    62.         {
    63.             if (this.Favorites == null)
    64.             {
    65.                 // Create new into database
    66.                 this.Favorites = new ProfileFavorite();
    67.                 this.Favorites.Profile = this.Profile;
    68.                 this.Favorites.GameValue = this.Game.Id;
    69.             }
    70.  
    71.             // ERROR HERE!!!
    72.             // The SelectedValue is a string representation of the Id of the selected weapon and map
    73.             // so I convert them to an integer and assign them to the WeaponId / MapId properties
    74.             // (which in turn load the corresponding Weapon and Map behind the scenes)
    75.             this.Favorites.WeaponId = int.Parse(cboWeapons.SelectedValue);
    76.             this.Favorites.MapId = int.Parse(cboMaps.SelectedValue);
    77.  
    78.             // Finally save it to the database
    79.             ProfileFavoriteManager.Instance.Save(this.Favorites);
    80.         }
    81.     }
    When loading the UserControls dynamically into their TabPanels, I set the Game, Profile and Favorites properties which determine from which user and from which game to load the data from.

    I then store each of these controls in a List<EditFavoritesControl> which I keep in a Session variable.
    (this might be important)

    When the user clicks OK on the edit page after making his choices, I retrieve the list of edit controls from that Session variable and call the Save method on each of them. I have to store them in a Session variable, because I cannot load them from anywhere else (I cannot re-create them, as that would cause the user's selections to get lost obviously). If I don't store them, they will be lost on postback.

    This is where the problem finally occurs: whatever the user has selected in the dropdowns, the SelectedValue in the Save method is always what is was when the page loaded.

    For example, if I manually edit the database such that the favorite weapon for a particular user has Id 15, then that weapon is shown when the page loads. Then I can use the dropdown to select a different one. In the Save method after I click OK however, the SelectedValue is... 15.


    I've had a problem like this before, it seemed like I was always re-loading the user's previous choice (from the database), regardless of whether there is a postback or not. But I'm not doing that, I'm correctly checking in the Page_Load whether there's a postback or not. If it's a postback, I don't load the dropdowns a second time, and I don't select the user's value a second time.

    As far as I understand, this should be correct. At least I'm doing this all the time in other pages and it works there.


    Maybe the ViewState isn't stored somehow?

    I can see two reasons that this might happen:
    - The TabContainer / TabPanel does some funky stuff that keeps my DropdownList selections from updating,
    - Storing the entire UserControl (multiple instances) in a Session variable does not store the selected values somehow (it is storing the control instances and its properties (the Game, Profile, etc) but maybe not the selected values in the dropdowns?)

    In either case, I have no clue how to fix it...


    Any help? Thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width