Woody
Woody

Reputation: 1189

Populate Listbox on window load

Here's my situation. I have a solution coded where I type a string into a textbox and upon clicking an Add button, it populates the Listbox.

Now, I want to:

a) Save that string to an XML file immediately. b) When the window opens, I want to display the data from that XML file in the listbox

Here's what I got so far:

Class

    public class Accounts : 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));
            }
        }
    }
}

Code Behind

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

        public Account()
        {
            InitializeComponent();        
            this.accountListBox.ItemsSource = AccountList;
        }

        private void addBtn_Click(object sender, RoutedEventArgs e)
        {
            AccountList.Add(new Accounts { AccountName = accountaddTextBox.Text });
        }

XAML

<ListBox DisplayMemberPath="AccountName" Height="164" HorizontalAlignment="Left" Margin="12" Name="accountListBox" VerticalAlignment="Top" Width="161" />

This code works for populating the listbox after you hit the Add button.

I've tried adding an instance of XMLTextReader to Window_Loaded and use an ArrayList as well to try to read the XML file and load it, but when I use ItemsSource it comes back with an error that I have to use ItemControl.ItemsSource...

Here's what I have tried, but it fails:

private void Window_Loaded(object sender, RoutedEventArgs e)
        {           
            XmlTextReader reader = new XmlTextReader("Accounts.xml");
            ArrayList ar = new ArrayList();

            //  Loop over the XML file
            while (reader.Read())
            {
                //  Here we check the type of the node, in this case we are looking for element
                if (reader.NodeType == XmlNodeType.Element)
                {
                    //  If the element is "accounts"
                    if (reader.Name == "Accounts")
                    {
                        ar.Add(reader.Value);

                        accountListBox.ItemsSource = ar;
                    }
                }
            }

            reader.Close();
        }

Upvotes: 0

Views: 806

Answers (2)

Greg Sansom
Greg Sansom

Reputation: 20840

It sounds like your just having trouble binding an ArrayList to the ListBox.

You're code isn't ideal but it looks like it should work.

Try running the below code and see what it gives you. If it works you might try comparing that to the code you have in your project and seeing what the differences are.

ArrayList ar = new ArrayList();
ar.Add("hello");
ar.Add("world");
this.accountListBox.ItemsSource = ar;

If you still don't have any luck please post the exact text of the error so we know what we're trying to fix...

Upvotes: 0

Ankesh
Ankesh

Reputation: 4885

Make a ViewModel as AccountListViewModel

public class AccountListViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Accounts> accountList= 
                                           newObservableCollection<Accounts>();
    private string accountName;
    ICommand AddAccountCommand {get;set;}

    public event PropertyChangedEventHandler PropertyChanged;

    public AccountListViewModel()
    {
        ReadAllAccountsFromXml();
        AddAccountCommand=new  RelayCommand(AddAccountToListAndSave);
    }

    private void ReadAllAccountsFromXml()
    {           
        XmlTextReader reader = new XmlTextReader("Accounts.xml");


        //  Loop over the XML file
        while (reader.Read())
        {
            //  Here we check the type of the node, in this case we are looking for element
            if (reader.NodeType == XmlNodeType.Element)
            {
                //  If the element is "accounts"
                if (reader.Name == "Accounts")
                {
                    var account = new Accounts()
                    account.AccountName=reader.Value;
                    AccountList.Add(account)
                }
            }
        }

        reader.Close();
    }

    private void AddAccountToListAndSave(object obj)
    {
        var account = new Accounts();
        account.AccountName=AccountnName;
        AccountList.Add(account);
        SaveListToXml();
    }

    private void SaveListToXml()
    {
        //Write Xml Saving Code Here With Object as AccountList
    }
    public ObservableCollection<Accounts> AccountList
    {
        get { return accountList; }
        set
        {
            accountList = value;
            OnPropertyChanged("AccountList");
        }
    }
    public string AccountName
    {
        get { return accountnName; }
        set
        {
            accountnName = value;
            OnPropertyChanged("AccountName");
        }
    }

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

In your Xaml.cs

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

    public Account()
    {
        InitializeComponent();        
        this.DataContext= new AccountListViewModel();
    }

}

IN your Xaml

<ListBox Height="164" HorizontalAlignment="Left" Margin="12" Name="accountListBox" VerticalAlignment="Top" Width="161" ItemSource=AccountList>
<ListBox.ItemTemplate>
    <DataTemplate>
         <TextBlock Text={Binding Path=AccountName}/>
    </DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

<TextBox Text={Binding Path=AccountName,UpdateSourceTrigger=PropertyChanged}></TextBox>

<Button Command={Binding Path=AddAccountCommand}/>

I believe this should do it....

Upvotes: 1

Related Questions