Woody
Woody

Reputation: 1189

Populate ListBox

I have a window with a textbox and a submit button. When pressing the submit button, the data in the textbox should populate into the listbox and be saved.

What's the best way of doing this? I tried a recommendation (using ObservableCollection) from an earlier question I had, but I can't seem to get it work. I have tried implementing it like this:

I created a class:

public class AccountCollection
{
    private string accountName;
    public string AccountName
    {
        get { return accountName; }
        set { accountName = value; }
    }
    public AccountCollection(string accountName)
    {
        AccountName = accountName;
    }
}        

Assigned the binding in my XAML:

<ListBox ItemsSource="{Binding AccountName, Mode=TwoWay}" IsSynchronizedWithCurrentItem="True" Height="164" HorizontalAlignment="Left" Margin="12" Name="accountListBox" VerticalAlignment="Top" Width="161" SelectionChanged="accountListBox_SelectionChanged" />

...and finally, when a user clicks the submit button from another window that contains the Submit button and textbox:

private void okBtn_Click(object sender, RoutedEventArgs e)
{
    BindingExpression expression = okBtn.GetBindingExpression(accountaddTextBox.Text);
    expression.UpdateSource();
}

But alas, I'm getting nowhere. I get an error message at the GetBindingExpression section:

Argument 1: cannot convert from 'string' to 'System.Windows.DependencyProperty'

What's obvious to me here is that when I created the class I didn't specify anything about the account name from the textbox, so I don't even know if the class is correct.

I'm basically confused and don't know what to do. Any help would be appreciated...

Upvotes: 0

Views: 1197

Answers (3)

emybob
emybob

Reputation: 1333

MODEL

// the model is the basic design of an object containing properties
// and methods of that object. This is an account object.

public class Account : INotifyPropertyChanged
{
    private string m_AccountName;

    public event PropertyChangedEventHandler PropertyChanged;

    public string AccountName
    {
       get { return m_AccountName;}
       set 
         { 
            m_AccountName = value;
            OnPropertyChanged("AccountName");
         }
    }

    protected void OnPropertyChanged(string name)
    {
      PropertyChangedEventHandler handler = PropertyChanged;
      if (handler != null)
      {
          handler(this, new PropertyChangedEventArgs(name));
      }
    }
}

ListBox XAML

 <ListBox Name="MyAccounts" DisplayMemberPath="AccountName" />

CODE BEHIND

// create a collection of accounts, then whenever the button is clicked,
//create a new account object and add to the collection.

public partial class Window1 : Window
{
    private ObservableCollection<Account> AccountList = new ObservableCollection<Account>();

    public Window1()
    {
        InitializeComponent();
        AccountList.Add(new Account{ AccountName = "My Account" });
        this.MyAccounts.ItemsSource = AccountList;
    }
     private void okBtn_Click(object sender, RoutedEventArgs e)
    {
       AccountList.Add(new Account{ AccountName = accountaddTextBox.Text});
    }
}

edit: added displaymemberpath on listbox xaml

Upvotes: 2

Ankesh
Ankesh

Reputation: 4885

Here is a Demo using MVVM approach

ViewModel

public class AccountListViewModel : INotifyPropertyChanged
{

    ICommand AddAccountCommand {get; set;}

    public AccountListViewModel()
    {
        AccountList = new ObservableCollection<string>();
        AddAccountCommand= new RelayCommand(AddAccount);
        //Fill account List saved data
        FillAccountList();
    }

    public AddAccount(object obj)
    {
        AccountList.Add(AccountName); 
        //Call you Model function To Save you lIst to DB or XML or Where you Like
        SaveAccountList()   
    }

    public ObservableCollection<string> AccountList 
    { 
            get {return accountList} ; 
            set
            {
                accountList= value
                OnPropertyChanged("AccountList");
            } 
    }

    public string AccountName 
    { 
            get {return accountName } ; 
            set
            {
                accountName = value
                OnPropertyChanged("AccountName");
            } 
    }

}

Xaml Binding

<ListBox ItemsSource="{Binding Path=AccountList}" Height="164" HorizontalAlignment="Left" Margin="12" Name="accountListBox" VerticalAlignment="Top" Width="161" />

<TextBox Text={Binding Path=AccountName}></TextBox>
<Button Command={Binding Path=AddAccountCommand}><Button>

Xaml.cs Code

    # region Constructor

    /// <summary>
    /// Default Constructor
    /// </summary>
    public MainView()
    {
        InitializeComponent();
        this.DataContext = new AccountListViewModel();
    }

    # endregion

The Implementation of INotifyPropertyChanged and forming porpeties is left upto you

Upvotes: 2

Felix C
Felix C

Reputation: 1775

Your ItemsSource for your ListBox is AccountName, which is only a string but not a collection.

You need to create a viewmodel (your datacontext for the view) like this:

public class ViewModel
{
    public ViewModel()
    {
        Accounts = new ObservableCollection<string>();
    }

    public ObservableCollection<string> Accounts { get; set; }
}

Bind ItemsSource to Accounts property:

<ListBox ItemsSource="{Binding Accounts}" Height="164" HorizontalAlignment="Left" Margin="12" Name="accountListBox" VerticalAlignment="Top" Width="161" />

And then, in your click event handler of the button you can simple add the current value of the textbox to your collection:

private void okBtn_Click(object sender, RoutedEventArgs e)
{
    Accounts.Add(accountaddTextBox.Text);
}

But don't forget to set the DataContext of your window to the class ViewModel.

Upvotes: 1

Related Questions