Intersoft ClientUI 8 > ClientUI Fundamentals > Commanding Overview > Commanding Walkthroughs > Walkthrough: Change Data Source from ViewModel using DelegateCommand |
This walkthrough shows how to change the data source from within the ViewModel which is triggered from toolbar buttons that are bound to a DelegateCommand in the ViewModel class.
In this walkthrough, you perform the following tasks:
You need the following components to complete this walkthrough:
The first step is to create a new ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template in Visual Studio.
This section shows how to create the Todo model class that represents the data entity used in this walkthrough. The Todo model class contains constructors to easily parse data from XML.
C# |
Copy Code
|
---|---|
private string _title; public string Title { get { return _title; } set { if (_title != value) { _title = value; OnPropertyChanged("Title"); } } } |
C# |
Copy Code
|
---|---|
public class Todo : ModelBase { private string _title; private string _notes; private string _category; private string _tags; private DateTime? _created; private DateTime? _due; private bool _isCompleted; public string Title { get { return _title; } set { if (_title != value) { _title = value; OnPropertyChanged("Title"); } } } public string Notes { get { return _notes; } set { if (_notes != value) { _notes = value; OnPropertyChanged("Notes"); } } } public string Category { get { return _category; } set { if (_category != value) { _category = value; OnPropertyChanged("Category"); } } } public string Tags { get { return _tags; } set { if (_tags != value) { _tags = value; OnPropertyChanged("Tags"); } } } public DateTime? Created { get { return _created; } set { if (_created != value) { _created = value; OnPropertyChanged("Created"); } } } public DateTime? Due { get { return _due; } set { if (_due != value) { _due = value; OnPropertyChanged("Due"); } } } public bool IsCompleted { get { return _isCompleted; } set { if (_isCompleted != value) { _isCompleted = value; OnPropertyChanged("IsCompleted"); } } } public Todo() { } public Todo(XElement x) { _title = !String.IsNullOrEmpty(x.Element("Title").Value.Trim()) ? x.Element("Title").Value.Trim() : ""; _notes = !String.IsNullOrEmpty(x.Element("Notes").Value.Trim()) ? x.Element("Notes").Value.Trim() : ""; _category = !String.IsNullOrEmpty(x.Element("Category").Value.Trim()) ? x.Element("Category").Value.Trim() : ""; _tags = !String.IsNullOrEmpty(x.Element("Tags").Value.Trim()) ? x.Element("Tags").Value.Trim() : ""; _created = !String.IsNullOrEmpty(x.Element("Created").Value.Trim()) ? DateTime.Parse(x.Element("Created").Value.Trim()) : (Nullable<DateTime>)null; _due = !String.IsNullOrEmpty(x.Element("Due").Value.Trim()) ? DateTime.Parse(x.Element("Due").Value.Trim()) : (Nullable<DateTime>)null; _isCompleted = bool.Parse(x.Element("IsCompleted").Value.Trim()); } } |
This section steps you through the process of creating a page that uses a variety of ClientUI controls such as UXListBox, UXToolBar, and UXToolBarButton. The UXListBox is used to display a collection of Todo data, while the UXToolBarButton is used to execute the command which change the data source of the UXListBox.
For more information on how to add a new item in Visual Studio, see Walkthrough: Add New Item such as Page, Dialog Box and Window in VS 2010 |
OverflowHandleVisibility | AsNeeded |
GripHandleVisibility | Collapsed |
Intersoft:DockPanel.Dock | Top |
FillChildMode | Custom |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot"> <Grid Width="500" Height="300"> <Intersoft:DockPanel FillChildMode="Last"> <Intersoft:UXToolBar OverflowHandleVisibility="AsNeeded" GripHandleVisibility="Collapsed" Intersoft:DockPanel.Dock="Top" FillChildMode="Custom"> </Intersoft:UXToolBar> </Intersoft:DockPanel> </Grid> </Grid> |
ButtonAppearance | ThreeD |
ItemSpacing | 0 |
CornerRadius | 4 |
Height | 25 |
BorderThickness | 1 |
BorderBrush | #FFB3B3B3 |
XAML |
Copy Code
|
---|---|
<Intersoft:UXToolGroup ButtonAppearance="ThreeD" ItemSpacing="0" CornerRadius="4" Height="25" BorderThickness="1" BorderBrush="#FFB3B3B3"> </Intersoft:UXToolGroup> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXToolBarButton Content="Today" Width="60" HorizontalContentAlignment="Center" IsToggleButton="True" GroupName="DateGroup" IsChecked="True" ToolTipService.ToolTip="View today's todo list" /> <Intersoft:UXToolBarButton Content="Next" Width="60" HorizontalContentAlignment="Center" IsToggleButton="True" GroupName="DateGroup" ToolTipService.ToolTip="View the next todo list" /> |
Intersoft:DockPanel.IsFillElement | True |
HorizontalAlignment | Center |
Margin | -96,0,0,0 |
CornerRadius | 4 |
XAML |
Copy Code
|
---|---|
<Intersoft:UXToolGroup Intersoft:DockPanel.IsFillElement="True" HorizontalAlignment="Center" Margin="-96,0,0,0" CornerRadius="4"> </Intersoft:UXToolGroup> |
Content | To Do's |
Background | {x:Null} |
BorderBrush | {x:Null} |
FontSize | 14 |
XAML |
Copy Code
|
---|---|
<Intersoft:StylishLabel Content="To Do's" Background="{x:Null}" BorderBrush="{x:Null}" FontSize="14"/> |
This section steps you through the process of creating a ViewModel class that contains the properties to describe the View that you created in previous section. The ViewModel defines the ToDoCollection to represent an observable collection of ToDoViewModel and a DelegateCommand to represent the view command and logic which changes the ToDo data source dynamically at runtime.
To create the TodoViewModel
C# |
Copy Code
|
---|---|
private Todo _todo; public TodoViewModel(Todo todo) { this._todo = todo; } public Todo Todo { get { return this._todo; } } public Visibility DueDateVisibility { get { return this.Todo.Due == null ? Visibility.Collapsed : Visibility.Visible ; } } |
To create the TodoListViewModel
C# |
Copy Code
|
---|---|
public class TodoListViewModel : ViewModelBase { } |
C# |
Copy Code
|
---|---|
private ObservableCollection<TodoViewModel> _todoCollection; private ObservableCollection<TodoViewModel> _filterTodo; private DelegateCommand _viewCommand; private string _todoListOption; public TodoListViewModel() { this.LoadToDo(); _viewCommand = new DelegateCommand(ExecuteViewCommand); ExecuteViewCommand("Today"); } public ObservableCollection<TodoViewModel> FilterToDo { get { return _filterTodo; } set { if (_filterTodo != value) { _filterTodo = value; OnPropertyChanged("FilterToDo"); } } } public DelegateCommand ViewCommand { get { return _viewCommand; } set { if (_viewCommand != value) { _viewCommand = value; OnPropertyChanged("ViewCommand"); } } } public string TodoListOption { get { return _todoListOption; } set { if (this._todoListOption != value) { _todoListOption = value; OnPropertyChanged("TodoListOption"); } } } public void ExecuteViewCommand(object parameter) { TodoListOption = parameter.ToString(); if (TodoListOption.Equals("Today")){ var list = this._todoCollection.Where(a => a.Todo.Due == new DateTime(2010, 8, 9) || a.Todo.Due == null).OrderBy(a => a.Todo.IsCompleted).ToList(); this.FilterToDo = new ObservableCollection<TodoViewModel>(list); }else { var list = this._todoCollection.Where(a => a.Todo.Due > new DateTime(2010, 8, 9) && !a.Todo.IsCompleted).OrderBy(a => a.Todo.IsCompleted).ToList(); this.FilterToDo = new ObservableCollection<TodoViewModel>(list); } } public ObservableCollection<TodoViewModel> TodoCollection { get { return _todoCollection; } set { if (_todoCollection != value) { _todoCollection = value; OnPropertyChanged("TodoCollection"); } } } public void LoadToDo() { this._todoCollection = new ObservableCollection<TodoViewModel>(); StreamResourceInfo source = System.Windows.Application.GetResourceStream(new Uri("/ChangeDataSourceFromVMUsingDelegateCommand;component/SampleData/TodoDataSource.xml", UriKind.Relative)); XDocument doc = XDocument.Load(source.Stream); var todos = from x in doc.Descendants("Todo") select new Todo(x); foreach (var dt in todos) { this._todoCollection.Add(new TodoViewModel(dt)); } source.Stream.Close(); } |
In the previous sections, you have learned how to create the Model and ViewModel classes, as well as the View that contains the user interface and controls used in this walkthrough. This section shows how to instantiate the ViewModel in the XAML page and bind the UI elements to the properties in the ViewModel such as the data context, selection and command.
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage... xmlns:ViewModels="clr-namespace:ChangeDataSourceFromVMUsingDelegateCommand.ViewModels" > </Intersoft:UXPage> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage...> <Intersoft:UXPage.Resources> <ViewModels:TodoListViewModel x:Key="TodoListViewModel" /> ... </Intersoft:UXPage.Resources> </Intersoft:UXPage> |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot" DataContext="{StaticResource TodoListViewModel}"> </Grid> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXToolGroup... > <Intersoft:UXToolBarButton Content="Today" Width="60" HorizontalContentAlignment="Center" IsToggleButton="True" GroupName="DateGroup" IsChecked="True" ToolTipService.ToolTip="View today's todo list" CommandParameter="Today" Command="{Binding ViewCommand}" /> <Intersoft:UXToolBarButton Content="Next" Width="60" HorizontalContentAlignment="Center" IsToggleButton="True" GroupName="DateGroup" ToolTipService.ToolTip="View the next todo list" Command="{Binding ViewCommand}" CommandParameter="Next" /> </Intersoft:UXToolGroup> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage...> <Intersoft:UXPage.Resources> ... <DataTemplate x:Key="listToDoItemTemplate"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="25" /> <ColumnDefinition Width="380" /> <ColumnDefinition Width="60" /> </Grid.ColumnDefinitions> <Intersoft:UXCheckBox IsChecked="{Binding Todo.IsCompleted}" /> <StackPanel Grid.Column="1"> <TextBlock TextWrapping="Wrap" Text="{Binding Todo.Category}" /> <TextBlock TextWrapping="Wrap" Text="{Binding Todo.Title}" /> <TextBlock Text="{Binding Todo.Notes}" /> <TextBlock TextWrapping="Wrap" Text="{Binding Todo.Tags}" /> </StackPanel> <Intersoft:StylishLabel Content="{Binding Todo.Due, StringFormat=\{0:MM/dd/yy\}}" Visibility="{Binding DueDateVisibility}" Grid.Column="2" VerticalAlignment="Center" MinWidth="50" CornerRadius="4" /> </Grid> </DataTemplate> </Intersoft:UXPage.Resources> </Intersoft:UXPage> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXListBox ItemTemplate="{StaticResource listToDoItemTemplate}" ItemsSource="{Binding FilterToDo}" /> |
In this walkthrough you have learned how to create ClientUI MVVM Project using project template, and create the classes and page based on the Model, View and ViewModel pattern. You also learned how to bind UXListBox to a collection of data, and the UXToolBarButton to a DelegateCommand in the ViewModel which performs data source changes that automatically reflect the data presented in UXListBox.
To learn more about UI development using MVVM pattern, see MVVM Pattern Overview. To learn more about commanding, see Commanding Overview.
This section lists the complete code used in this walkthrough.
C# |
Copy Code
|
---|---|
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using ChangeDataSourceFromVMUsingDelegateCommand.ViewModels; using System.Xml.Linq; using System.Globalization; namespace ChangeDataSourceFromVMUsingDelegateCommand.Models { public class Todo : ModelBase { private string _title; private string _notes; private string _category; private string _tags; private DateTime? _created; private DateTime? _due; private bool _isCompleted; public string Title { get { return _title; } set { if (_title != value) { _title = value; OnPropertyChanged("Title"); } } } public string Notes { get { return _notes; } set { if (_notes != value) { _notes = value; OnPropertyChanged("Notes"); } } } public string Category { get { return _category; } set { if (_category != value) { _category = value; OnPropertyChanged("Category"); } } } public string Tags { get { return _tags; } set { if (_tags != value) { _tags = value; OnPropertyChanged("Tags"); } } } public DateTime? Created { get { return _created; } set { if (_created != value) { _created = value; OnPropertyChanged("Created"); } } } public DateTime? Due { get { return _due; } set { if (_due != value) { _due = value; OnPropertyChanged("Due"); } } } public bool IsCompleted { get { return _isCompleted; } set { if (_isCompleted != value) { _isCompleted = value; OnPropertyChanged("IsCompleted"); } } } public Todo() { } public Todo(XElement x) { _title = !String.IsNullOrEmpty(x.Element("Title").Value.Trim()) ? x.Element("Title").Value.Trim() : ""; _notes = !String.IsNullOrEmpty(x.Element("Notes").Value.Trim()) ? x.Element("Notes").Value.Trim() : ""; _category = !String.IsNullOrEmpty(x.Element("Category").Value.Trim()) ? x.Element("Category").Value.Trim() : ""; _tags = !String.IsNullOrEmpty(x.Element("Tags").Value.Trim()) ? x.Element("Tags").Value.Trim() : ""; _created = !String.IsNullOrEmpty(x.Element("Created").Value.Trim()) ? DateTime.Parse(x.Element("Created").Value.Trim()) : (Nullable<DateTime>)null; _due = !String.IsNullOrEmpty(x.Element("Due").Value.Trim()) ? DateTime.Parse(x.Element("Due").Value.Trim()) : (Nullable<DateTime>)null; _isCompleted = bool.Parse(x.Element("IsCompleted").Value.Trim()); } } } |
C# |
Copy Code
|
---|---|
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using ChangeDataSourceFromVMUsingDelegateCommand.Models; namespace ChangeDataSourceFromVMUsingDelegateCommand.ViewModels { public class TodoViewModel : ViewModelBase { private Todo _todo; public TodoViewModel(Todo todo) { this._todo = todo; } public Todo Todo { get { return this._todo; } } public Visibility DueDateVisibility { get { return this.Todo.Due == null ? Visibility.Collapsed : Visibility.Visible ; } } } } |
C# |
Copy Code
|
---|---|
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Intersoft.Client.Framework.Input; using ChangeDataSourceFromVMUsingDelegateCommand.Models; using System.Collections.ObjectModel; using System.Windows.Resources; using System.Xml.Linq; using System.Linq; namespace ChangeDataSourceFromVMUsingDelegateCommand.ViewModels { public class TodoListViewModel : ViewModelBase { private ObservableCollection<TodoViewModel> _todoCollection; private ObservableCollection<TodoViewModel> _filterTodo; private DelegateCommand _viewCommand; private string _todoListOption; public TodoListViewModel() { this.LoadToDo(); _viewCommand = new DelegateCommand(ExecuteViewCommand); ExecuteViewCommand("Today"); } public ObservableCollection<TodoViewModel> FilterToDo { get { return _filterTodo; } set { if (_filterTodo != value) { _filterTodo = value; OnPropertyChanged("FilterToDo"); } } } public DelegateCommand ViewCommand { get { return _viewCommand; } set { if (_viewCommand != value) { _viewCommand = value; OnPropertyChanged("ViewCommand"); } } } public string TodoListOption { get { return _todoListOption; } set { if (this._todoListOption != value) { _todoListOption = value; OnPropertyChanged("TodoListOption"); } } } public void ExecuteViewCommand(object parameter) { TodoListOption = parameter.ToString(); if (TodoListOption.Equals("Today")){ var list = this._todoCollection.Where(a => a.Todo.Due == new DateTime(2010, 8, 9) || a.Todo.Due == null).OrderBy(a => a.Todo.IsCompleted).ToList(); this.FilterToDo = new ObservableCollection<TodoViewModel>(list); }else { var list = this._todoCollection.Where(a => a.Todo.Due > new DateTime(2010, 8, 9) && !a.Todo.IsCompleted).OrderBy(a => a.Todo.IsCompleted).ToList(); this.FilterToDo = new ObservableCollection<TodoViewModel>(list); } } public ObservableCollection<TodoViewModel> TodoCollection { get { return _todoCollection; } set { if (_todoCollection != value) { _todoCollection = value; OnPropertyChanged("TodoCollection"); } } } public void LoadToDo() { this._todoCollection = new ObservableCollection<TodoViewModel>(); StreamResourceInfo source = System.Windows.Application.GetResourceStream(new Uri("/ChangeDataSourceFromVMUsingDelegateCommand;component/SampleData/TodoDataSource.xml", UriKind.Relative)); XDocument doc = XDocument.Load(source.Stream); var todos = from x in doc.Descendants("Todo") select new Todo(x); foreach (var dt in todos) { this._todoCollection.Add(new TodoViewModel(dt)); } source.Stream.Close(); } } } |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Intersoft="http://intersoft.clientui.com/schemas" xmlns:ViewModels="clr-namespace:ChangeDataSourceFromVMUsingDelegateCommand.ViewModels" mc:Ignorable="d" x:Class="ChangeDataSourceFromVMUsingDelegateCommand.Views.TodoList" Title="UXPage1 Page" > <Intersoft:UXPage.Resources> <ViewModels:TodoListViewModel x:Key="TodoListViewModel" /> <DataTemplate x:Key="listToDoItemTemplate"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="25" /> <ColumnDefinition Width="380" /> <ColumnDefinition Width="60" /> </Grid.ColumnDefinitions> <Intersoft:UXCheckBox IsChecked="{Binding Todo.IsCompleted}" /> <StackPanel Grid.Column="1"> <TextBlock TextWrapping="Wrap" Text="{Binding Todo.Category}" /> <TextBlock TextWrapping="Wrap" Text="{Binding Todo.Title}" /> <TextBlock Text="{Binding Todo.Notes}" /> <TextBlock TextWrapping="Wrap" Text="{Binding Todo.Tags}" /> </StackPanel> <Intersoft:StylishLabel Content="{Binding Todo.Due, StringFormat=\{0:MM/dd/yy\}}" Visibility="{Binding DueDateVisibility}" Grid.Column="2" VerticalAlignment="Center" MinWidth="50" CornerRadius="4" /> </Grid> </DataTemplate> </Intersoft:UXPage.Resources> <Grid x:Name="LayoutRoot" DataContext="{StaticResource TodoListViewModel}"> <Grid Width="500" Height="300"> <Intersoft:DockPanel FillChildMode="Last"> <Intersoft:UXToolBar OverflowHandleVisibility="AsNeeded" GripHandleVisibility="Collapsed" Intersoft:DockPanel.Dock="Top" FillChildMode="Custom"> <Intersoft:UXToolGroup ButtonAppearance="ThreeD" ItemSpacing="0" CornerRadius="4" Height="25" BorderThickness="1" BorderBrush="#FFB3B3B3"> <Intersoft:UXToolBarButton Content="Today" Width="60" HorizontalContentAlignment="Center" IsToggleButton="True" GroupName="DateGroup" IsChecked="True" ToolTipService.ToolTip="View today's todo list" CommandParameter="Today" Command="{Binding ViewCommand}" /> <Intersoft:UXToolBarButton Content="Next" Width="60" HorizontalContentAlignment="Center" IsToggleButton="True" GroupName="DateGroup" ToolTipService.ToolTip="View the next todo list" Command="{Binding ViewCommand}" CommandParameter="Next" /> </Intersoft:UXToolGroup> <Intersoft:UXToolGroup Intersoft:DockPanel.IsFillElement="True" HorizontalAlignment="Center" Margin="-96,0,0,0" CornerRadius="4"> <Intersoft:StylishLabel Content="To Do's" Background="{x:Null}" BorderBrush="{x:Null}" FontSize="14"/> </Intersoft:UXToolGroup> </Intersoft:UXToolBar> <Intersoft:UXListBox ItemTemplate="{StaticResource listToDoItemTemplate}" ItemsSource="{Binding FilterToDo}" /> </Intersoft:DockPanel> </Grid> </Grid> </Intersoft:UXPage> |
C# |
Copy Code
|
---|---|
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Intersoft.Client.UI.Navigation; using ChangeDataSourceFromVMUsingDelegateCommand.ViewModels; namespace ChangeDataSourceFromVMUsingDelegateCommand.Views { public partial class TodoList : UXPage { public TodoList() { InitializeComponent(); } // Executes when the user navigates to this page. protected override void OnNavigatedTo(NavigationEventArgs e) { } } } |