Lesson 19.5 – Changing dropdown default values

Lesson objectives

At the end of this lesson, you will know how to…

  • Set the default selected item in a dropdown
  • Prepare to make a change to an existing program

 

A reader mentioned a problem they saw when the player has more than one weapon. When the player moves to a new location, the dropdown for weapons always selects the first weapon in the list.

If the player wants to fight with a different weapon, the reader wanted to have the dropdown always select that weapon – unless the player manually changed weapons again.

Here is how to do that.

 

Planning

Before you change an existing program, it’s good to think about everything it will affect.

This seems like a simple change. However, we should make some additional changes when we do this.

For example, store the currently selected weapon in the save game file. This way, when the player restarts the game, they will have their last weapon selected.

If we think a little more, we realize that the player may already have a saved game file, without a value for the currently selected weapon in it. So, in the code to read the currently selected weapon from the save game file, we need to deal with a file that does not have that value in it.

This is the type of thing to watch out for when you modify a program.

 

Saving and reloading player information

Step 1: Open the SuperAdventure solution in Visual Studio and select the Player class to modify.

Add a new property to store the player’s current weapon. I added this under the “CurrentLocation” property (although you could add it anywhere outside of a function):

 

Step 2: Open the code file for the SuperAdventure.cs form.

In the lesson where we save and restore the game state in a file, we connected a function to the FormClosing event. This function is an “event handler”, it “handles” the closing “event”. In that lesson, we let Visual Studio connect the event to the function automatically. For this lesson, we need to connect the function manually. You’ll see why in a minute.

Add this function to SuperAdventure.cs:

This gets the selected item from the cboWeapons dropdown and saves it in the player’s CurrentWeapon property.

Notice that we have “(Weapon)” in front of “cboWeapons.SelectedItem”. That’s because a dropdown can hold different types of objects, and cboWeapons.SelectedItem could be any datatype. By adding “(Weapon)” in front of it, we are “casting” it to the Weapon datatype.

We can do this because the items in the dropdown are Weapon objects, so the casting will work.

We need to do this, because the CurrentWeapon property only holds Weapon objects. It can’t take a generic SelectedItem object.

 

Step 3: Now we need to change the code that populates the cboWeapons dropdown. We want it to select the player’s CurrentWeapon (if they have one) and connect to the cboWeapons_SelectedIndexChanged function (for when the player changes the value in the dropdown list).

Find the “UpdateWeaponsListInUI” function and change it to the code below:

Look at the lines before and after where we set the cboWeapons.DataSource. These lines connect, or disconnect, a function to the SelectedIndexChanged event of cboWeapons.

In the line before setting the datasource, we remove the function connected to the dropdown’s “SelectedIndexChanged event (the line with the “-=”). That’s because when you set the DataSource property of a dropdown, it automatically calls the function connected to the SelectedIndexChanged event. We don’t want that to happen. We only want that event called when the player manually changes the value.

After the DataSource is set, we add the event handler function back to the SelectedIndexChanged event (with the “+=”). This way, the function will run when the player changes the value.

At the end of this function, we have code to check if the player has a value in their CurrentWeapon property. If they do, we set the dropdown’s SelectedItem to that weapon. If the player doesn’t have a CurrentWeapon, we default to the first one.

 

Step 4: Now we need to update the save game and load game functions. Go back to editing the Player.cs file.

Find the “ToXmlString” function and add this code after the section for saving the current location:

This will save the ID of the player’s currently selected weapon (if they have one).

 

Next, find the “CreatePlayerFromXmlString” function and add this code after the lines to set the CurrentLocation:

This will load the player’s currently selected weapon, if one exists in the save game file.

Now, we’re finished. When the player changes their active weapon, that value will stay set when they move to a new location, or if they exit and resume the game. It makes the game a little easier for the player, which is always a good thing to do with your programs.

 

Check your work

Build the solution and make sure there are no errors in the “output” box at the bottom of Visual Studio. If you see any problems, double-check the changes you made in this lesson.

 

Summary

The important thing from this lesson is that you need to think before making a change to an existing program. What else could your change affect?

This is why some programmers create unit tests and use continuous integration. With those, your can make a change and quickly know if it broke anything else.

 

Source code for this lesson

Get it from GitHub: https://gist.github.com/ScottLilly/4a0c6ed8e55b89bbd789

or DropBox: Lesson 19.5 – https://www.dropbox.com/sh/oays76i8eq46yhy/AABCjkj-VLZ1x1h_OyKh99g5a?dl=0

 

Next lesson: Lesson 19.6 – Increase maximum hit points when the player gains a level

Previous lesson: Lesson 19.4 – Saving and loading the player information

All lessons: Learn C# by Building a Simple RPG Index

16 thoughts on “Lesson 19.5 – Changing dropdown default values

  1. Hey! great tutorial! are you planning on showing us how to add armor, magic, merchants, etc…?  Its a fun and enjoyable way to learn C#.

    1. Thank you. I’ve just restarted working on a project for a version of the gam that can have many more features. The current source code (very early stuff) is here: https://github.com/ScottLilly/ScottsOpenSourceRPG. If you follow it on GitHub, you’ll see the updates as it gets more features. I’ll probably write a few tutorials on how I do some of the things in this game, but not a complete step-by-step guide.

  2. So I started getting 5 errors on this part.

     

    4 are from the 4 movement/location changing buttons
    Error CS1061 ‘object’ does not contain a definition for ‘LocationToEast’ and no extension method ‘LocationToEast’ accepting a first argument of type ‘object’ could be found (are you missing a using directive or an assembly reference?)

    The 5th is from the a different section of the SuperAdventure.cs

    Error CS1061 ‘IEnumerable<PlayerQuest>’ does not contain a definition for ‘Add’ and no extension method ‘Add’ accepting a first argument of type ‘IEnumerable<PlayerQuest>’ could be found (are you missing a using directive or an assembly reference?)

     

    Any help would be great, thanks in advance as I have loved working on this project.

    1. These are the first things I would check. If they do not solve the problem, can you upload your solution (all files) to GitHub, or Dropbox, and send me the link to it, so I can investigate some more?

      In the Location, class, make sure the LocationTo properties are public, like this:

      public Location LocationToNorth { get; set; }
      public Location LocationToEast { get; set; }
      public Location LocationToSouth { get; set; }
      public Location LocationToWest { get; set; }

      For the problem with “IEnumerable“, check the Player class. Make sure you have this line in the “using” statements area

      using System.Collections.Generic;

      … that the Quests property is defined this way:

      public List Quests { get; set; }

      … and that you have this line in the constructor, to initialize the Quests property:

      Quests = new List();

    1. It looks like there are several problems in the Player class. It should look like the code here: https://gist.github.com/ScottLilly/4a0c6ed8e55b89bbd789.

      The error for the locations properties is happening because the Player.CurrentLocation is an internal field, with an “object” datatype, in your solution. It needs to be a property that is a Location datatype. The datatypes for the Quests and Inventory properties are IEnumerable, in your solution. Those need to be List datatype, instead of IEnumerable. List has an Add property on it (to add items to the list). IEnumerable does not implement an Add method – which is why you are getting those errors.

      Let me know if fixing the Player class does not solve the problems.

  3. I have copied the Player.cs and SuperAdventure.cs from that location before.

    I apologize but I am not sure how you are suggesting I fix these. I have followed the instructions as I thought by the directions on each chapter so I am not sure why it is doing something different from what you are saying it should.

    1. I just noticed that there is a second Player class in your solution. There is one in the Engine project (where it should be) and another one in the SuperAdventure project. The one in the SuperAdventure project is the one with the problems. And, the UI is using that Player class.

      If you delete the Player.cs file in the SuperAdventure project, the game should use the Engine project’s Player class – which looks like it has the correct code.

  4. Hello again, Mr. Lilly.

    After completing the base tutorial, I’ve made several additions (abilities, Strength and Defense stats, UI changes that let the user see monster statistics at a glance, encounter rates, etc…) in the idea of greatly expanding on the concept, and I’ve learned a lot. During playtesting, the most requested feature to be added was to have the game remember their weapon selection. Luckily for me, you already have a tutorial on the matter! I tried to implement it on my own, but apparently there are a lot of shortcomings of comboboxes that I am unaware of, which shows how far I have to go. My unsuccessful solution was very close to yours, though.

    It does the job fantastically. There is something I’d like to change about it, however. When a battle begins, it briefly shows the default selection in the combobox before changing over to the stored selection. It’s a small issue, I know, but it irks me, and I feel that making this change will make for a more immersive experience. Can you point me in the right direction?

      1. That fixed it! I hadn’t gotten that far into the lessons, as anything past lesson 18 I considered beyond the base tutorial. It works perfectly for weapons, and it should work perfectly after I expand on items and add more consumable types. I still have to get it to work for abilities (they use their own combobox and, the way the class is written, can’t be implemented the exact same way as weapons and potions), but I’m sure I can figure it out sooner or later.

        Thank you again, Mr. Lilly. Your website continues to be a great source of knowledge and practice.

Leave a Reply

Your email address will not be published. Required fields are marked *