Resolved How can I change the way, an item of a comboBox is presented as a string?

Wkesther

Member
Joined
Aug 6, 2022
Messages
24
Programming Experience
Beginner
Hello, as mentioned in the title, I want to display an item of a comboBox in a textblock as a string. On the first image below you can see how it is currently displayed. The item of the comboBox is called "vegetarisch" and thats also what should only be displayed in the textblock.

Thats how the cathegory is presented.PNG
ComboBoxItem.PNG


Thats the recipe class with the categoryProperty:

RecipeClass:
namespace recipeBook.Classes
{
    public class Recipe
    {
        [PrimaryKey, AutoIncrement]
        public int ID { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public string Preparation{ get; set; }
        public string Ingredients { get; set; }
    }
}
 
The item of the comboBox is called "vegetarisch"

Not really sure what that means, but if you override ToString() then the item in the combo will show up as your overridden return string

Example:

C#:
    public class Recipe
    {
        [PrimaryKey, AutoIncrement]
        public int ID { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public string Preparation{ get; set; }
        public string Ingredients { get; set; }
    }

    public override string ToString(){
        return Name;
    }


   ...
  combo.Items.Add(new Recipe { Name = "vegetarisch" });

then the item added per above, will show as "vegtarisch"

If you make e.g.

C#:
    public override string ToString(){
        return $"{Category}/{Name}";
    }

Then a Add(new Recipe{ Name = "world", Category = "hello"}); will show as "hello/world"
 
I hope that the following pictures and code can help you understand my problem a bit better.

Image Files were too large, so I had to upload them.
MainWindow: Main-Window
showRecipeWindow: show-Recipe-Window

MouseDoubleClickEvent of the MainWindow:
MouseDoubleClick - Event:
private void recipeListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            Recipe recipe = recipeListView.SelectedItem as Recipe;
            ShowRecipeWindow showRecipeWindow = new ShowRecipeWindow(recipe);
            showRecipeWindow.Show();
        }

showRecipeWindow - Code:
showRecipeWindow:
namespace recipeBook
{
    public partial class ShowRecipeWindow : Window
    {
        public ShowRecipeWindow(Recipe recipe)
        {
            InitializeComponent();

            this.Title = recipe.Name;

            recipeNameTb.Text = recipe.Name;
            ingredientsTb.Text = recipe.Ingredients;
            cathegoryTb.Text = recipe.Category.ToString();
            preperationTb.Text = recipe.Preparation;
        }
    }
}
 
I have to admit, I'm now more confused than I was before. I thought we were talking about a combo, but you now have an event handler for a listview and 4 textboxes. Has the query about the combo box been resolved and you're now asking about something else?
 
Haha okay, I am really sorry that I confused you even more. The application I create is a recipebook, where recipes can be added. The added recipes are than listed in a listview, which is located in the middle of the MainWindow. When you want to open a recipe, you have to double click on its name in the listview. By doubleclicking it, an event fires and a new window opens up with all informations of the recipe shown in textblocks. My problem is that the category of the recipe is displayed like that:

1660743015726.png


But I want to display the category of the recipe without "System.Windows.Controls.ComboBoxItem:".

The category of the recipe is selected in a comboBox, when adding the recipe.
 
I think you probably haven't shown the relevant code. The textbox shows what it does because of this line:

C#:
cathegoryTb.Text = recipe.Category.ToString();

Category is a string already, so there's no point ToString()ing it, but in either case, the Category string must surely be set to "System.Windows.Controls.ComboBoxItem: vegetarisch" so the fault lies with the code that sets the Category property in the first place

None of the code you have posted has Category = in so we can't see how it's set. Perhaps it's something like this (I don't use the GUI toolkit you're using):

C#:
    var r = new Recipe();
    r.Category = categoryCombo.SelectedComboBoxItem.ToString(); //this line has a problem; it's getting the wrong thing and putting it in Category

If you want targeted advice, post the code that sets the Category; at the moment I recommend that you check that code because it seems it's not putting just the chosen item's text in as the category string
 
OK, so put a breakpoint on that line, run the program, make a new recipe etc and then when the program stops in the debugger, with the yellow bar highlighting the line, use the Locals window to look at the properties you have available on the object behind SelectedItem; one of them should be just a string of "vegetarisch". Use that instead of ToString()
 
I tried to use "categoriesComboBox.SelectedItem.Content" instead of "categoriesComboBox.SelectedItem.ToString(), but it wont let me use "Content".
1660745357299.png

This are the only options available:
1660745664263.png


But I found an alternative solution for my problem. I know...it might not be the cleanest and best solution...but it works.... :

C#:
            if (categoriesComboBox.SelectedItem.ToString().Contains("vegetarisch"))
                recipe.Category = "vegetarisch";
            else if (categoriesComboBox.SelectedItem.ToString().Contains("Fleisch"))
                recipe.Category = "Fleisch";
            else if (categoriesComboBox.SelectedItem.ToString().Contains("Fisch"))
                recipe.Category = "Fisch";
            else if (categoriesComboBox.SelectedItem.ToString().Contains("vegan"))
                recipe.Category = "vegan";
            else if (categoriesComboBox.SelectedItem.ToString().Contains("Dessert"))
                recipe.Category = "Dessert";
            else if (categoriesComboBox.SelectedItem.ToString().Contains("proteinreich"))
                recipe.Category = "Proteinreich";
            else
                recipe.Category = "no Category";
 
it wont let me use "Content"

Because C# is strongly typed; SelectedItem returns Object, which can hold anything. In your particular case it's holding an instance of type ComboBoxItem but it "looks like" an Object. You'll have to cast it to tell the C# compiler to treat it as anything more specific:


C#:
recipe.Category = (categoriesComboBox.SelectedItem as ComboBoxItem).Content as string;

.Content is also declared to return object so that too must be cast to a string in order to assign it to a property that is typed as taking a string
 
Last edited:
it might not be the cleanest and best solution

It's certainly a headache to maintain. If you're going the route of a dirty hack, would it not be simpler to just replace System.Windows.Controls.ComboBoxItem: with nothing?

C#:
  recipe.Category = categoriesComboBox.SelectedItem.ToString().Replace("System.Windows.Controls.ComboBoxItem: ", "")

Or cut the string after the colon...

Or split it on colon-space and take the second entry...

Or...

(All these are nasty; don't do them.. But I mention them because they're all at the very least more dynamic than your approach of hard coding the names in. Strive to avoid making code that, as soon as some data changes, somewhere, you have to edit, build and release a whole new app)
 
Because C# is strongly typed; SelectedItem returns Object, which can hold anything. In your particular case it's holding an instance of type ComboBoxItem but it "looks like" an Object. You'll have to cast it to tell the C# compiler to treat it as anything more specific:


C#:
recipe.Category = (categoriesComboBox.SelectedItem as ComboBoxItem).Content as string;

.Content is also declared to return object so that too must be cast to a string in order to assign it to a property that is typed as taking a string
Thanks, it works fine now and certainly looks better than my "solution". I appreciate your help very much. :)
 
The above coding mess is what happens when:
  1. The UI is used as the data model or to store data instead of just using the UI as view into the data model;
  2. WPF code is being written code ala WinForms instead of using MVVM or some other design pattern that clearly marks where the UI ends and the Model starts.
 
Okay, thank you for the explanation. I am currently learning the MVVM pattern. I just wanted to practice a bit with several functions of WPF, SQlite and Linq. When I am finished learning MVVM I will of course use it.
I just want to thank you guys, for helping me with any problem I come across. You are the best :)
 
Back
Top Bottom