none
MVVM pattern in WPF RRS feed

  • Question

  • I Have the following application with MainWindow.xaml , MainWindow.xaml.cs,

    GridViewModel.cs and GridModel.cs

    I want to know is this app is in proper MVVM format , it gets its data from a WCF service,

    in the Model service is initiated and in View Model is Getdata and Updata methods in View

    Data is bound to GridControl and data values are updated in the MainWindow.xaml.cs file

    I donot use Inotifypropertychanged interface ,

    I initiate the Model in View Model like

    GridModel gm=new GridMode();

    and then initiate ViewModel in View like

    GridViewModel gym=new GridViewModel();

    then access there methods , so is this in proper MVVM and if there ae shortcomings then what changes do I need to make.

    MainWindow.xaml

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
            xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" xmlns:dxn="http://schemas.devexpress.com/winfx/2008/xaml/navbar" x:Class="UsingWCFServiceInWPFApp.MainWindow"
            xmlns:local="clr-namespace:UsingWCFServiceInWPFApp" Title="MainWindow" Height="482" Width="1150">
        <!--<Window.DataContext>
            <local:GridModel/>
        </Window.DataContext> ItemsSource="{Binding emp}"-->
        <Grid>
            <DockPanel>
                <dxg:GridControl x:Name="GcView" DesignTimeShowSampleData="False" AutoGenerateColumns="AddNew"
                                 EnableSmartColumnsGeneration="True" Width="828" >
                    <dxg:GridControl.Resources>
                        <SolidColorBrush x:Key="UnfocusedRowBrush" Color="#FFDDDDDD" />
                        <ControlTemplate xmlns:dxi="http://schemas.devexpress.com/winfx/2008/xaml/core/internal"
          xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys"
          x:Key="{dxgt:GridRowThemeKey IsThemeIndependent=True, ResourceKey=RowTemplate}"
          TargetType="{x:Type dxg:RowControl}">
                            <Grid>
                                <Border x:Name="Background" Background="{TemplateBinding Background}" />
                                <Border x:Name="BottomLine" BorderThickness="0,0,0,1" BorderBrush="{TemplateBinding BorderBrush}" VerticalAlignment="Bottom" />
                                <Grid x:Name="PART_LayoutPanel" />
                                <dx:SimpleButton x:Name="PART_EditButton" Content="Edit" Glyph="{dx:DXImage Image=Edit_16x16.png}"
            Command="{Binding View.Commands.ShowEditForm}" Visibility="Collapsed" HorizontalAlignment="Right" Margin="4" Padding="30,4" />
                                </Grid>
                            <ControlTemplate.Triggers>
                                <MultiDataTrigger>
                                    <MultiDataTrigger.Conditions>
                                        <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True" />
                                        <Condition Binding="{Binding IsEditFormVisible}" Value="False" />
                                    </MultiDataTrigger.Conditions>
                                    <Setter TargetName="PART_EditButton" Property="Visibility" Value="Visible" />
                                </MultiDataTrigger>
                                <Trigger Property="ShowHorizontalLine" Value="False">
                                    <Setter Property="Visibility" Value="Collapsed" TargetName="BottomLine" />
                                </Trigger>
                                <Trigger Property="ShowBottomLine" Value="True">
                                    <Setter Property="Visibility" Value="Visible" TargetName="BottomLine" />
                                </Trigger>
                                <Trigger Property="FadeSelection" Value="True">
                                    <Setter Property="Background" Value="{StaticResource UnfocusedRowBrush}" />
                                </Trigger>
                                <Trigger Property="ShowRowBreak" Value="True">
                                    <Setter Property="BorderThickness" Value="{dxi:ThemeResource {dxgt:GridRowThemeKey ResourceKey=RowBreakThickness}}" TargetName="BottomLine" />
                                    <Setter Property="BorderBrush" Value="{dxi:ThemeResource {dxgt:GridRowThemeKey ResourceKey=RowBreakBrush}}" TargetName="BottomLine" />
                                </Trigger>
                                <Trigger Property="FixedRowPosition" Value="Bottom">
                                    <Setter Property="VerticalAlignment" Value="Top" TargetName="BottomLine" />
                                </Trigger>
                                <Trigger Property="IsLastFixedRow" Value="True">
                                    <Setter Property="BorderThickness" Value="0,1,0,1" TargetName="BottomLine" />
                                    <Setter Property="Background" Value="{dxi:ThemeResource {dxgt:GridRowThemeKey ResourceKey=RowSeparatorBrush}}" TargetName="BottomLine" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </dxg:GridControl.Resources>
                    <dxg:GridControl.View>
                        <dxg:TableView EditFormShowMode="InlineHideRow" ShowEditFormOnDoubleClick="False" ShowEditFormOnEnterKey="False" ShowEditFormOnF2Key="False" RowUpdated="TableView_RowUpdated" />
                    </dxg:GridControl.View>
                    <dxg:GridColumn x:Name="EmpID" FieldName="EmpID" ReadOnly="True" EditFormVisible="False"/>
                    <dxg:GridColumn x:Name="Name" FieldName="Name"/>
                    <dxg:GridColumn x:Name="Email" FieldName="Email"/>
                    <dxg:GridColumn x:Name="Gender" FieldName="Gender"/>
                    <dxg:GridColumn x:Name="Phone" FieldName="Phone"/>
                </dxg:GridControl>
            </DockPanel>
            <DockPanel>
                <dx:SimpleButton x:Name="Showdata" Content="Show Data" HorizontalAlignment="Left" Height="41" Margin="6,172,0,0" VerticalAlignment="Top" Width="115" Click="SimpleButton_Click"/>
            </DockPanel>

        </Grid>
    </Window>

           

    MainWindow.xaml.cs
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using DevExpress.Xpf.Grid;
    using DevExpress.Mvvm;
    using DevExpress.Mvvm.POCO;
    using DevExpress.Mvvm.UI;
    using DevExpress.Office.Services;
    using DevExpress.Xpf.Core;
    using DevExpress.Xpf.Utils;
    using DevExpress.XtraEditors.DXErrorProvider;
    using DevExpress.XtraEditors;
    using UsingWCFServiceInWPFApp.ViewModels;
    namespace UsingWCFServiceInWPFApp
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            GridViewModel gvm = new GridViewModel();
            public MainWindow()
            {
                InitializeComponent();
                ShowData();
            }
            private void SimpleButton_Click(object sender, RoutedEventArgs e)
            {
                ShowData();
            }
           
            public void ShowData()
            {
                GcView.ItemsSource = gvm.GetData().Tables[0].DefaultView;
            }
            private void TableView_RowUpdated(object sender, DevExpress.Xpf.Grid.RowEventArgs e)
            {
                 ServiceReference1.Employee objemp = new ServiceReference1.Employee();
                 objemp.EmpID = GcView.GetCellValue(e.RowHandle, "EmpID").ToString();
                 objemp.Email = GcView.GetCellValue(e.RowHandle, "Email").ToString();
                 objemp.Gender = GcView.GetCellValue(e.RowHandle, "Gender").ToString();
                 objemp.Phone = GcView.GetCellValue(e.RowHandle, "Phone").ToString();
                 objemp.Name = GcView.GetCellValue(e.RowHandle, "Name").ToString();
                 MessageBox.Show(gvm.UpdateData(objemp));
           }
         
        }
    }

    GridViewModel.cs

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using UsingWCFServiceInWPFApp;

    namespace UsingWCFServiceInWPFApp.ViewModels
    {
        class GridViewModel
        {
            GridModel gm = new GridModel();
            public DataSet GetData()
            {
                DataSet ds = new DataSet();
                ds = gm.emp.GetEmployeeRecords();
                return ds;
            }

            public string UpdateData(ServiceReference1.Employee objemp)
            {
                return gm.emp.UpdateEmployeeDetails(objemp);
            }
        }
    }

    GridModel.cs


    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace UsingWCFServiceInWPFApp
    {
        class GridModel
        {
            ServiceReference1.EmployeeServiceClient _emp = new ServiceReference1.EmployeeServiceClient();
            public ServiceReference1.EmployeeServiceClient emp
            {
                set { _emp = value; }
                get { return _emp; }
            }
        }
    }

    • Edited by RohitJGcT1 Saturday, April 1, 2017 10:55 PM
    Saturday, April 1, 2017 10:44 PM

All replies

  • In my option, your pattern is UI-Business Logic-Data Access layer. It is not MVVM, you are missing ViewModel. The view binds to properties on a ViewModel, which, in turn, exposes data contained in model objects and other state specific to the view. The bindings between view and ViewModel are simple to construct because a ViewModel object is set as the DataContext of a view. If property values in the ViewModel change, those new values automatically propagate to the view via data binding. When the user clicks a button in the View, a command on the ViewModel executes to perform the requested action.

    I suggest you refer the links below:

    #Patterns - WPF Apps With The Model-View-ViewModel Design Pattern

    https://msdn.microsoft.com/en-us/magazine/dd419663.aspx

    #WPF MVVM step by step (Basics to Advance Level)

    https://www.codeproject.com/Articles/819294/WPF-MVVM-step-by-step-Basics-to-Advance-Level

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, April 3, 2017 2:35 AM
  • The requirement for this application is that, it must use a WCF Service which implements the Employee class and exposes the Insert, Update , Delete and Get operations the following is the WCF service code I am using, Is there a way to implement Inotifypropertychanged and other MVVM features in this , its this service’s servicereference that is initiated in the WPF model and its methods are then used in the ViewModel.

     

    IEmployeeService.cs

     

    using System;

    using System.Collections.Generic;

    using System.Data;

    using System.Linq;

    using System.Runtime.Serialization;

    using System.ServiceModel;

    using System.ServiceModel.Web;

    using System.Text;

    using System.ComponentModel;

    using System.Drawing;

    using System.Runtime.CompilerServices;

     

     

    namespace EmployeeServices

    {

        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together. 

        [ServiceContract]

        public interface IEmployeeService

     

        {

            [OperationContract]

            string InsertEmployeeRecord(Employee emp);

     

            [OperationContract]

            DataSet GetEmployeeRecords();

     

            [OperationContract]

            string DeleteRecord(Employee emp);

     

            [OperationContract]

            string UpdateEmployeeDetails(Employee emp);

        }

     

     

        // Use a data contract as illustrated in the sample below to add composite types to service operations. 

        [DataContract]

        public class Employee

        {

     

            string _empID = "";

            string _name = "";

            string _email = "";

            string _phone = "";

            string _gender = "";

     

            [DataMember]

            public string EmpID

            {

                get { return _empID; }

                set { _empID = value; }

            }

     

            [DataMember]

            public string Name

            {

                get { return _name; }

                set { _name = value; }

            }

     

            [DataMember]

            public string Email

            {

                get { return _email; }

                set { _email = value; }

            }

     

            [DataMember]

            public string Phone

            {

                get { return _phone; }

                set { _phone = value; }

            }

     

            [DataMember]

            public string Gender

            {

                get { return _gender; }

                set { _gender = value; }

            }

        }

    }

    Monday, April 3, 2017 8:39 AM
  • In my option, your current design is OK. There is no need to must use one Design Pattern.

    If you insist on MVVM, I suggest you create a new ViewModel which will implement OnPropertyChanged and ICommand. All the button click event will call ICommand function. And the WCF service will be called in ICommand and OnPropertyChanged to operate the data.

    For more information about ViewModel, I would suggest you refer the links in my first reply.


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, April 4, 2017 5:15 AM
  • How will I update in the dataset in the ICommand in the View model as my UpdateDate Method is in the WCF service
    Tuesday, April 4, 2017 7:20 PM
  • You could call WCF Service from ICommand. 

    Here is a simple code:

    #region Commands
            void UpdateArtistNameExecute()
            {
                //this is used to call WCF Service by Service client
                ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
                string reuslt= client.GetData(123);
                ArtistName = reuslt;
            }
    
            bool CanUpdateArtistNameExecute()
            {
                return true;
            }
    
            public ICommand UpdateArtistName { get { return new RelayCommand(UpdateArtistNameExecute, CanUpdateArtistNameExecute); } }
            #endregion 

    I suggest you refer below link for more information.

    #WCF by Example - Chapter VIII - WPF Client - Relay Command

    https://www.codeproject.com/Articles/109988/WCF-by-Example-Chapter-VIII-WPF-Client-Relay-Comma

    In addition, if you have any new specific issues, I would suggest you post new threads, and then we could focus on these new issues.


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, April 5, 2017 3:28 AM