0

Well, here is my XAML code:

<ComboBox Grid.Row="2"
          Grid.Column="1"
          Margin="10"
          Width="250"
          Height="30"
          VerticalAlignment="Top"
          HorizontalAlignment="Left"
          ItemsSource="{Binding AllProducts}"
          SelectedItem="{Binding SelectedProduct}"/>

And this is my C# code:

private ObservableCollection<Product> allProducts = new ObservableCollection<Product>();
public ObservableCollection<Product> AllProducts
{
    get => allProducts;
    set
    {
        db.Products.Select(x => x).AsObservableCollection();
        RaisePropertyChangedEvent(nameof(AllProducts));
    }
}

All I want to do is to select all products from my database and the simply add it to the ComboBox. But somehow it does not work. No error and no exception.

X39
  • 789
  • 6
  • 22
nivopo_10
  • 23
  • 4
  • I believe you are missing three key settings on the ComboBox - Take a look at this question/answer: [Binding a WPF ComboBox to a custom list](https://stackoverflow.com/questions/561166/binding-a-wpf-combobox-to-a-custom-list) – JayV Jan 17 '21 at 20:17
  • Welcome to Stack Overflow! I can see that you have recently posted many questions about C# and WPF. It's great that you are learning, and there is nothing wrong with asking for help here, but it's best to look for other resources online first, like tutorials and other posts. There is a wealth of information online to get you started. Here are some resources that might help: [The Complete C# Tutorial](https://csharp.net-tutorials.com), [The Complete WPF Tutorial](https://wpf-tutorial.com), [.NET API Browser](https://docs.microsoft.com/dotnet/api/). Don't run before you can walk. Best of luck! – Callum Watkins Jan 18 '21 at 00:38

3 Answers3

1

Here is your solution, Make your combobox like this

 <ComboBox x:Name="comboBox" Grid.ColumnSpan="2" Grid.Column="1" 
                  HorizontalAlignment="Left" Margin="0,63,0,0" Grid.Row="5" VerticalAlignment="Top" Width="282"
                  ItemsSource="{Binding AllProducts}"
                  SelectedValuePath="ID" DisplayMemberPath="Code"
                  SelectedItem="{Binding SelectedProduct}"/>

then viewmodel take two property like this

 private ObservableCollection<AllProducts> _allProducts;
        public ObservableCollection<AllProducts> AllProducts
        {
            get { return _allProducts; }
            set
            {
                _allProducts = value;
                base.NotifyOfPropertyChange(nameof(AllProducts));
            }
        }



 private AllProducts _selectedProduct;
    public AllProducts SelectedProduct
    {
        get { return _selectedProduct; }
        set
        {
            _selectedProduct = value;
            base.NotifyOfPropertyChange(nameof(SelectedProduct));
        }
    }

I have made my AllProducts.cs like this

public class AllProducts
    {
        public long ID { get; set; }
        public string Code { get; set; }
    }

thats all. here i attached my final output as a screen shot

View

0

I think this is true

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

protected void RaisePropertyChangedEvent(string propName)
{
   if (this.PropertyChanged != null)
   {
      PropertyChanged(this, new PropertyChangedEventArgs(propName));
   }
}
#endregion



private ObservableCollection<Product> allProducts = new ObservableCollection<Product>();
public ObservableCollection<Product> AllProducts
{
   get => allProducts;
   set
   {
      this.allProducts = db.Products.Select(x => x).AsObservableCollection();
      RaisePropertyChangedEvent("AllProducts");
   }
}
Meysam Asadi
  • 6,438
  • 3
  • 7
  • 17
0

The issue you have is at your properties set implementation.

private ObservableCollection<Product> allProducts = new ObservableCollection<Product>();
public ObservableCollection<Product> AllProducts
{
    // AllProducts-get returns the private field allProducts
    get => allProducts;
    // AllProducts-set changes the private field allProducts
    set
    {
        this.allProducts = db.Products.Select(x => x).AsObservableCollection();
        RaisePropertyChangedEvent(nameof(AllProducts));
    }
}

Please do note that you have to update your AllProducts collection if you want to update the contents of the combobox. Changing db.Products will not alter the frontend.

I may also leave some additional tip here, drawing the usage of nameof(AllProducts) obsolete:

void RaisePropertyChangedEvent([System.Runtime.CompilerServices.CallerMemberName] string callee = "")
{
    ...
}

Adding the CallerMemberName attribute will automatically fill out the callers member name (in the case of AllProducts, "AllProducts"), making copy-paste issues less likely

X39
  • 789
  • 6
  • 22