Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Create Dynamic XAML Forms with the Presentation Model Pattern : Page 3

Harness this powerful user interface pattern to XAML forms to simplify capturing unbounded sets of data.


advertisement
Finishing Up
Your ListView definition is essentially complete, but to keep this article compact, I've left out an important part; you'll have to dig into the included sample code to see it. That omitted code uses another DataTemplate with an IValueConverter to change the date formatting on the startDateTemplate's ComboBox.

With the ListView defined, you can add event handlers to the XAML code-behind that delegate the process of adding and removing ExpenseLineItems to ExpenseSheetWindowModel. You need to know the index of the ListViewItem the user wants to add or remove (the index of the item where the user clicked the 'Add' or "Delete" button), so you can insert a line item after that index or remove the line item at that index. In the sample code, the addButton_Click and deleteButton_Click event handlers walk up the visual tree to locate the ListViewItem and pass it to the ListView's ItemContentGenerator method to get the index:

Author's Note: Josh Smith, MVP helped me find the index of ListViewItems in this thread.

private void addButton_Click( object sender, RoutedEventArgs e) { int index = GetListViewItemIndex( e.OriginalSource as DependencyObject); presentationModel.InsertRowIntoCurrentExpenseSheet( index + 1, new ExpenseLineItem()); } private void deleteButton_Click( object sender, RoutedEventArgs e) { ItemCollection items = lineItemListView.Items; // don't delete last item if (items.Count == 1) { return; } int index = GetListViewItemIndex( e.OriginalSource as DependencyObject); presentationModel.RemoveRowFromCurrentExpenseSheet(index); } private int GetListViewItemIndex(DependencyObject depObj) { while (!(depObj is ListViewItem)) { depObj = VisualTreeHelper.GetParent(depObj); } return lineItemListView.ItemContainerGenerator. IndexFromContainer(depObj); }

The corresponding ExpenseSheetWindowModel methods simply modify the ExpenseSheet's ObservableCollection of ExpenseLineItems. Because this is an ObservableCollection, modifications fire PropertyChanged events and the UI redraws itself:

public void RemoveRowFromCurrentExpenseSheet(int index) { CurrentExpenseSheet.LineItems.RemoveAt(index); } public void InsertRowIntoCurrentExpenseSheet( int index, ExpenseLineItem lineItem) { CurrentExpenseSheet.LineItems.Insert(index, lineItem); }

Extending the Principles
In this article, you have seen how the Presentation Model pattern aids in building dynamic user interfaces with multiple editable line items. As you examine the included sample code, you'll see how ExpenseSheetWindowModel drives other parts of the UI, not discussed here, such as the navigation (the green arrow and square buttons in the top left in Figure 1). You can build upon the ideas shown here to develop UIs that might not necessarily display line items but that require multiple editable components with different layouts to capture unbounded sets of data.

The Presentation Model pattern lets you encapsulate the state of a user interface and its behavior. One could argue the method bodies for this example are small enough to fit inside the XAML code-behind and that the Presentation Model adds an unwarranted layer of complexity. For the small case above that might be true, but as you build larger UIs, the logic can quickly become unwieldy. When coupled with other chores such as launching background threads for long operations, setting the state of the mouse cursor, and displaying progress indicators and message boxes, code gets muddled and starts to rot. The Presentation Model cleanly ties the UI to business objects in an abstract way, so you can build completely different UI's in the future without having to re-implement their core logic.



John Wheeler is a Senior Software Engineer at ComFrame Software Corporation, a Southeastern Microsoft Certified Gold Partner, and IBM Rational Partner who specializes in full project engagements. Aside from .NET, John is well versed in Java, Ruby on Rails, and lightweight development practices.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date