Nagashworshiper
Nagashworshiper

Reputation: 9

Linking a ComboBox with an ObservableCollection

I am trying to link a combobox with my ObservableCollection, however this does not seem to work, I have looked around and tried other ways that the internet is saying, but I can't seem to get it to work

public class UserData
{
    public string Key { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public string Application
    {
        get
        {
            return Text;
        }
    }
    public string Text { get; set; }
    public override string ToString()
    {
        return Text;
    }
}

private static ObservableCollection<UserData> _userdata = new ObservableCollection<UserData>();
    public static ObservableCollection<UserData> Userdata
    {
        get { return _userdata; }
        set { _userdata = value; }
    }
}

XAML

<ComboBox 
   HorizontalAlignment="Left" 
   Height="24" 
   Margin="5,3,0,0" 
   VerticalAlignment="Top" 
   Width="112" 
   x:Name="cbApplications" 
   DropDownClosed="cbApplications_DropDownClosed" 
   ItemsSource="{Binding Path=Userdata}"/>

Would anyone be able to support me in this matter?

Upvotes: 0

Views: 62

Answers (2)

Clemens
Clemens

Reputation: 128146

You should have a view model class like this:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<UserData> UserData { get; }
        = new ObservableCollection<UserData>();

    private UserData selectedUserData;

    public UserData SelectedUserData
    {
        get { return selectedUserData; }
        set
        {
            selectedUserData = value;
            PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(nameof(SelectedUserData)));
        }
    }
}

and bind to it like this:

<ComboBox ItemsSource="{Binding UserData}"
          SelectedItem="{Binding SelectedUserData}"
          DisplayMemberPath="Text"/>

In the constructor of your MainWindow (or some other appropriate place), initialize the view model and assign it to the DataContext property of the Window:

public MainWindow()
{
    InitializeComponent();

    var vm = new ViewModel();
    vm.UserData.Add(new UserData { Text = "User 1" });
    vm.UserData.Add(new UserData { Text = "User 2" });
    vm.UserData.Add(new UserData { Text = "User 3" });
    vm.SelectedUserData = vm.UserData[1];

    DataContext = vm;
}

Note that since you can set the ComboBox's DisplayMemberPath property (or declare an ItemTemplate) it's not necessary to override the ToString method of the UserData class.

Upvotes: 2

Sam
Sam

Reputation: 5392

Get rid of the static, is there a reason for that? Implement INotifyPropertyChanged in you class. Then add in your

set { _userdata = value; OnPropertyChanged("Userdata"); }

Also, for cleanliness you should move your Closed command to binding or ICommand unless you are needing to do something UI specific only that has no data content associated.

Let me know if that doesn't fix you.

Also a lot of times I like to make a base class to handle this.

 public abstract class BaseViewModel : INotifyPropertyChanged
{
    //MEMBERS
    public event PropertyChangedEventHandler PropertyChanged;


    //PROPERTIES
    public void OnPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

}

Then you can call it from your setter like:

OnPropertyChanged(); without any params.

Upvotes: 0

Related Questions