normal forms
- WPF us the normal way of doing .Net Windows UIs in 2014.
If you're working with WPF, you need to leave behind any and all notions you got from ancient technologies and understand and embrace The WPF Mentality.
Basically, you don't "iterate" over anything in WPF because there's absolutely no need to do so.
The UI's responsibility is to show data, not to store it nor manipulate it. Therefore whatever data you need to show must be stored in a proper Data Model or ViewModel and the UI must use proper DataBinding to access that, rather than procedural code.
So, for example, say you have a Person
class:
public class Person
{
public string LastName {get;set;}
public string FirstName {get;set;}
}
You will want to set the UI's DataContext to a list of that:
//Window constructor:
public MainWindow()
{
//This is required.
InitializeComponent();
//Create a list of person
var list = new List<Person>();
//... Populate the list with data.
//Here you set the DataContext.
this.DataContext = list;
}
Then you will want to show that in a ListBox
or another ItemsControl
-based UI:
<Window ...>
<ListBox ItemsSource="{Binding}">
</ListBox>
</Window>
And then you'll want to use WPF's Data Templating capabilities to define how to show each instance of the Person
class in the UI:
<Window ...>
<Window.Resources>
<DataTemplate x:Key="PersonTemplate">
<StackPanel>
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text="{Binding LastName"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<ListBox ItemsSource="{Binding}"
ItemTemplate="{StaticResource PersonTemplate}"/>
</Window>
Finally, if you need to change the Data at runtime, and have those changes reflected (shown) in the UI, your DataContext classes must Implement INotifyPropertyChanged
:
public class Person: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
OnPropertyChanged("LastName");
}
}
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
}
Finally you iterate over the List<Person>
and change the data items' properties rather than manipulating the UI:
foreach (var person in list)
person.LastName = "Something";
While leaving the UI alone.