Reputation: 1189
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
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
Reputation: 4885
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));
}
}
}
public partial class Account : Window
{
private ObservableCollection<Accounts> AccountList = new ObservableCollection<Accounts>();
public Account()
{
InitializeComponent();
this.DataContext= new AccountListViewModel();
}
}
<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