0

I'm having an issue with C# using WPF.

Just being brief here.
The following code below collects names via Entity Framework into a list.
This is in my MainWindow.xaml.cs file.

public ObservableCollection<string> FruitInfo
{
    get
    {
        using (var context = new Fruit())
        {
            ObservableCollection<string> fruits= new ObservableCollection<string>();
            foreach (var item in context.Fruits.OrderBy(s => s.FruitName))
            {
                fruits.Add(item.FruitName);
            }
            return fruits;
        }
    }
}

In my MainWindow.xaml file, I have the following:

<GroupBox Grid.Row="0" Grid.Column="0" Margin="5" Header="Fruit Info"  >
    <ComboBox Margin="5" SelectedItem="{Binding FruitInfo}"/>
</GroupBox>

When running my project, I see that the Combo Box does not populate the fruits.
Any ideas why I'm not seeing this?

All thoughts appreciated

5
  • Not even sure what you're trying to achieve here. Why do you call the Fruit(), what does it return, why are you using the using inside the get? can you elaborate? Commented Nov 23, 2013 at 12:53
  • The goal here is to return an ordered list of FruitNames from my database, and have them presented in a drop down list from my WPF. Commented Nov 23, 2013 at 14:53
  • I'm using 'using', to refer to the database, to create and return the observable collection. The 'get' will simply get the list. Commented Nov 23, 2013 at 15:01
  • @GabrielY.: could you try the modification as described in my answer? Commented Nov 23, 2013 at 17:16
  • Thanks for your help on this Mario. This has been resolved Commented Nov 24, 2013 at 23:41

3 Answers 3

2

You should bind the ItemsSource of the ComboBox to your collection, and the SelectedItem to another string that will represent the user's selection.

First:

<GroupBox Grid.Row="0" Grid.Column="0" Margin="5" Header="Fruit Info"  >
    <ComboBox Margin="5" ItemsSource="{Binding FruitInfo}" SelectedItem="{Binding SelectedFruit}"/>
</GroupBox>

Second: Make a SelectedFruit in your ViewModel

public string SelectedFruit { get; set; }
Sign up to request clarification or add additional context in comments.

Comments

0

Ok, I understand what your trying to do, even though I'm still not sure why you're trying to do it.

The idea of using using is that it creates the variable for you, and the disposes of it when you finish the block of code you're running.

Now, you're creating a variable in that block, and return it ... and then, the system tries to dispose of it. So your return collection must be implicitly convertible to System.IDisposable, which I doubt yours is.

Putting that aside, you should follow emedbo advice. You will bind the source to the collection, and have another property for the selected index (since you're using mvvm).

I wouldn't get the data like that inside a using inside a getter, since it feels like that data you're getting might be deleted, and if it's not, then the whole use of your using is a bit wrong.

Not to mention it's not very readable, and you should aim for readability in most cases.

Comments

-1

I don't use the Entity Framework, but I think the pattern for the FruitInfo property is missing of an important piece.

The problem is that the binding mechanism does not realize about the new ObservableCollection, because it expect some "notification" way to be alerted. That is, you have several ways to solve your problem:

  • use a DependencyPropety instead of an ordinary property: every time you set the property the bound controls are also notified.

I'd recommend this solution: reliable and versatile.

  • implement the INotifyPropertyChanged interface in the class exposing the FruitInfo property (e.g. MainWindow), then fire a PropertyChanged event on any actual FruitInfo's value changing.

This way is also valuable, but it looks useless adding a thing already exposed in any DependencyObject-derived class. The INotifyPropertyChanged fits perfectly for the POCO classes (Plain-Old CLR-Objects).

  • give a name to the combobox, then set the ItemsSource property explicitly.

It works fine, but you'd lose the benefits of the data-context inheritance, especially within templates.

  • the pattern you used creates the collection in a "lazy" fashion: consider avoiding the lazy-way, and set the FruitInfo value before the combobox is created/bound.

Doable, but typically may be applied in a few cases. Also requires that you know for sure the sequence of the objects creation. Keep as latest way.

== UPDATE

Try to modify your code as follows:

private ObservableCollection<string> _fruits = new ObservableCollection<string>();

public ObservableCollection<string> FruitInfo
{
  get
  {
    using (var context = new Fruit())
    {
        this._fruits.Clear();
        foreach (var item in context.Fruits.OrderBy(s => s.FruitName))
        {
            this._fruits.Add(item.FruitName);
        }
        return this._fruits;
    }
  }
}

2 Comments

-1 You're advicing a lot of different things, and most of them are purely bad practice.
@HighCore: the user has a problem, and I listed some ways to solve it. I don't think to be advised any bad practice, unless explicitly expressed. Bad practice, however, does not mean an minefield.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.