Search

Tuesday, April 9, 2013

Create Beautiful Dynamic UI’s using DataTemplates and MVVM

In yesterday’s post, I talked about MVVM and how easy it is to start building composite applications leveraging this innovative programming paradigm.  Until today, I was struggling with linking dynamically created UI elements to the view-model.  To take it one step further, I wanted the user interface to be bound fully (Two-Way) to the view-model and be automatically updated as the view-model changes.

What’s an example?  You have a view that prompts the user to input a count.  That count could be used to create Albums, Contacts or whatever ‘class’ you want.  Here’s the sample code for an Album.cs file:

public class Album
{
public string Artist { get; set; }
       public string Name { get; set; }
       public string Year { get; set; }
}

You can add this code to your view-model class:

private ObservableCollection<Album> albums = new ObservableCollection<Album>();
public ObservableCollection<Album> Albums
{
       get
       {
              return albums;
       }
       set
       {
              albums = value;
              OnPropertyChanged("Albums");
       }
}

Update your view code with the XAML below, link your DataContext to your view-model and as you add new Album objects to your Albums observable collection, they will automatically show up on your UI and be bound to the view-model.  Yes, it’s that simple to build rich UIs that are managed by user input at runtime.

<ListBox Width="510" ItemsSource="{Binding Path=Albums, Mode=TwoWay}" HorizontalContentAlignment="Stretch" BorderThickness="0">
  <ListBox.ItemTemplate>
     <DataTemplate>
       <StackPanel Orientation="Vertical">
         <StackPanel Orientation="Horizontal" Margin="0,5,0,0">
           <TextBlock Text="Artist:" Width="60" VerticalAlignment="Center"/>
           <TextBox Text="{Binding Path=Artist}" Width="100"/>
           <TextBlock Text="Name:" Width="60" Margin="5,0,0,0" VerticalAlignment="Center"/>
           <TextBox Text="{Binding Path=Name}" Width="210" />
           <TextBlock Text="Date:" Width="60" Margin="5,0,0,0" VerticalAlignment="Center"/>
           <TextBox Text="{Binding Path=Date}" Width="50" />  <!--Normally a date/year picker would be here-->
         </StackPanel>
       </StackPanel>
     </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

No comments:

Post a Comment