In this article, you will learn how to create object data source for UI elements, using Visual Studio and Microsoft Blend.
Before starting the tutorial, I assume that you are familiar with .NET 4.5 and Microsoft Blend for Visual Studio.
I have followed four principles along with MVVM pattern, in this article.
- Simplicity
- Blendability
- Designability
- Testability
Step 1
- Create a new WPF Application project. Here, I have created a project named as "Test".
Step 2
- Add a new folder to the project and rename it as "Model".
- Add a new class in "Model" folder, and rename it as "Person".
- Now, add the following code in "Person" class.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace Test.Model {
- publicclass Person {
- private int _ID;
- publicint ID {
- get {
- return _ID;
- }
- set {
- _ID = value;
- }
- }
- private string _Name;
- publicstring Name {
- get {
- return _Name;
- }
- set {
- _Name = value;
- }
- }
- private string _Address;
- publicstring Address {
- get {
- return _Address;
- }
- set {
- _Address = value;
- }
- }
- }
- }
- Again, add a new folder in the project, named as "Helper".
- Add a new class, "ViewModelBase" in Helper folder.
- Now, add the following code in ViewModelBase class.
-
- usingSystem;
- usingSystem.Collections.Generic;
- usingSystem.Linq;
- usingSystem.Text;
- usingSystem.Threading.Tasks;
- usingSystem.ComponentModel;
- usingSystem.Runtime.CompilerServices;
- namespaceTest.Helper {
- public abstract class ViewModelBase: INotifyPropertyChanged {
- public eventPropertyChangedEventHandler PropertyChanged;
- protected voidIPropertyChanged(string PropertyName) {
- PropertyChangedEventHandlerHandler = this.PropertyChanged;
- if (Handler != null) PropertyChanged(this, newPropertyChangedEventArgs(PropertyName));
- }
- protected boolSetProperty < T > (ref T Storage, T Value, [CallerMemberName] stringPropertyName = null) {
- if (EqualityComparer < T > .Default.Equals(Storage, Value)) return false;
- Storage = Value;
- IPropertyChanged(PropertyName);
- return true;
- }
- }
- }
With the release of Microsoft Visual Studio 2012 and .NET 4.5, the company has introduced some lovely features; for example, [CallerMemberName] makes its entrance.
With this new feature, you can write INotifyPropertyChanged (Interface) code without having to worry about renaming the properties.
- Add a new folder, "Service", in the project.
- Add new Interface named as "IPersonService" in Service folder.
- Add the following code in IPersonService.
- using System;
- usingSystem.Collections.Generic;
- using System.Linq;
- using System.Text;
- usingSystem.Threading.Tasks;
- namespace Test.Service {
- public interface IPersonService {
- IEnumerable < Model.Person > GetAllDetails();
- }
- }
- Add a new class in Service folder, named "PersonServiceDump".
- Add the following code in PersonServiceDump class.
- usingSystem;
- usingSystem.Collections.Generic;
- usingSystem.Linq;
- usingSystem.Text;
- usingSystem.Threading.Tasks;
- namespaceTest.Service {
- public class PersonServiceDump: IPersonService {
- public IEnumerable < Model.Person > GetAllDetails() {
- var List = new List < Model.Person > ();
- List.Add(new Model.Person() {
- ID = 101,
- Name = "Karthik",
- Address = "Pune",
- Department = "Tech",
- Team = "Dev"
- });
- return List;
- }
- }
- }
- Add another folder, "ViewModel", in the Test project, along with a new class "MainWindowViewMode".
- Add the following code in MainWindowViewModel.
- usingSystem;
- usingSystem.Collections.Generic;
- usingSystem.Linq;
- usingSystem.Text;
- usingSystem.Threading.Tasks;
- usingSystem.Collections.ObjectModel;
- namespaceTest.ViewModel {
- public class MainWindowViewModel: Helper.ViewModelBase {
- public MainWindowViewModel() {
- StartUp();
- }
- public void StartUp() {
- LoadAllDetails();
- }
- public void LoadAllDetails() {
- var Data = IService.GetAllDetails();
- MaserData = new ObservableCollection < Model.Person > (Data);
- }
- private ObservableCollection < Model.Person > _MaserData;
- public ObservableCollection < Model.Person > MaserData {
- get {
- return _MaserData;
- }
- set {
- SetProperty(ref _MaserData, value);
- }
- }
- private Service.IPersonService_IService;
- public Service.IPersonServiceIService {
- get {
- if (_IService == null) {
- _IService = new Service.PersonServiceDump();
- }
- return _IService;
- }
- set {
- _IService = value;
- }
- }
- }
- }
- Add a new folder named as "View", move the MainWindow.Xaml file in View folder, and change the namespace accordingly.
- Save all the changes.
Step 3
- Open the Test project in Microsoft Blend for Visual Studio.
- Add new List Box in Grid.
- I have the changed the Grid background and List Box background.
- We can change the brush from properties.
Step 4
- Click View, then choose Data Window, as shown below.
- Press "Create data source" and choose "Create Object Data Source".
- Choose MainWindowViewModel, then press OK.
- Drag MainWindowViewModel into Grid.
- Select MasterData, then drag it into List Box. Once it’s dragged, we can see the data in List Box.
- Save all the changes.
- Given below is the complete code of XAML.
- <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModel="clr-namespace:Test.ViewModel" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="Test.View.MainWindow" Title="MainWindow" Height="472.559" Width="768.939">
- <Window.Resources>
- <ViewModel:MainWindowViewModel x:Key="MainWindowViewModelDataSource" d:IsDataSource="True" />
- <DataTemplate x:Key="PersonTemplate">
- <StackPanel Orientation="Horizontal">
- <TextBlock Text="{BindingAddress}" Margin="5,0,20,0" />
- <TextBlock Text="{BindingID}" Margin="0,0,20,0" />
- <TextBlock Text="{BindingDepartment}" Margin="0,0,20,0" />
- <TextBlock Text="{BindingTeam}" Margin="0,0,20,0" />
- <TextBlock Text="{BindingName}" /> </StackPanel>
- </DataTemplate>
- </Window.Resources>
- <Grid DataContext="{Binding Source={StaticResourceMainWindowViewModelDataSource}}">
- <Grid.Background>
- <LinearGradientBrush EndPoint="0.58,0.883" StartPoint="0.567,0">
- <GradientStop Color="#FFA7B8B9" />
- <GradientStop Color="#FF71E1EC" Offset="1" /> </LinearGradientBrush>
- </Grid.Background>
- <ListBox HorizontalAlignment="Left" Height="240" Margin="241.21,84.839,0,0" VerticalAlignment="Top" Width="227" ItemsPanel="{DynamicResource ItemsPanelTemplate1}" ItemTemplate="{DynamicResource PersonTemplate}" ItemsSource="{BindingMaserData}" Foreground="White">
- <ListBox.Resources>
- <ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
- <VirtualizingStackPanelIsItemsHostVirtualizingStackPanelIsItemsHost="True">
- <VirtualizingStackPanel.Background>
- <LinearGradientBrushEndPointLinearGradientBrushEndPoint="0.5,1" StartPoint="0.5,0">
- <GradientStopColorGradientStopColor="Black" Offset="0" />
- <GradientStopColorGradientStopColor="#FF0CB2FF" Offset="1" /> </LinearGradientBrush>
- </VirtualizingStackPanel.Background>
- </VirtualizingStackPanel>
- </ItemsPanelTemplate>
- </ListBox.Resources>
- </ListBox>
- </Grid>
- </Window>
Conclusion
I hope you liked this useful article. Please provide your valuable feedback and suggestions.