0
\$\begingroup\$

I'm new to MVVM and WPF. Please suggest whether this is okay or I need to correct my understanding of MVVM which I confess is very limited as at the moment. The default namespace to all classes as MVVMDemo. Please go thru the code and help me with the questions that I have added at appropriate places in the code within comments.

ClsGlobal.cs

public class ClsGlobal
{
    public static EmployeeViewModel _EmpViewModel =null;
    public EmployeeViewModel EmpViewModel
    {
        get
        {
            if (_EmpViewModel == null) _EmpViewModel = new EmployeeViewModel();
            return _EmpViewModel;
        }
    }
}

EmployeeModel.cs

public class Employee
{

    private string _EmpId = "";
    public string EmpId
    {
        get { return _EmpId; }
        set
        {
            _EmpId = value;
        }
     }

    private string _EmpName = "";
    public string EmpName
    {
        get { return _EmpName; }
        set
        {
            _EmpName = value;
        }
    }

    private string _EmpDept = "";
    public string EmpDept
    {
        get { return _EmpDept; }
        set
        {
            _EmpDept = value;
        }
    }
}

EmployeeViewModel.cs

 public class EmployeeViewModel: INotifyPropertyChanged
{
    private Employee _CurrentRec;
    private Employee Temprec,BlankRec;
    private string _EmpId;
    private string _EmpName;
    private string _EmpDept;
    private bool _SearchFound=true;
    public bool SearchFound
    {
        get { return _SearchFound; }
        set
        {
            _SearchFound = value;

        }
    }
    public EmployeeViewModel()
    {
        LoadData();
        Temprec = new Employee();
        BlankRec = new Employee();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string Property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(Property));
        }
    }

    public ObservableCollection<Employee> Employees
    {
        get;set;

    }

    public Employee CurrentRec
    {
        get
        {
           if(_CurrentRec == null)
            {
                if(Employees==null||Employees.Count<=0)
                {
                    _CurrentRec = new Employee();
                    _CurrentRec.EmpId = _CurrentRec.EmpName = _CurrentRec.EmpDept = "";
                }
                else
                {
                    _CurrentRec = Employees.FirstOrDefault<Employee>();
                }
            }
            EmpId = _CurrentRec.EmpId;

            return _CurrentRec;
        }
        set
        {
            _CurrentRec = value;
            RaisePropertyChanged("CurrentRec");
        }
    }
    public string EmpId
    {
        get { return _EmpId; }
        set
        {
            string strTemp = _EmpId;
            _EmpId = value;
            RaisePropertyChanged("EmpId");
            if ((strTemp != null) && (strTemp != value))
            {
                Temprec = Employees.Where(item => item.EmpId.Equals(_EmpId)).FirstOrDefault();
                if (Temprec != null)
                {
                    _CurrentRec = Temprec;
                    if(_SearchFound == false)
                    {
                        _SearchFound = true;
                        RaisePropertyChanged("SearchFound");
                    }
                    RaisePropertyChanged("CurrentRec");

                }
                else
                {
                    //How to create a clone of _CurrentRec here??
                        Temprec = new Employee();
                        Temprec.EmpId = _CurrentRec.EmpId;
                        Temprec.EmpName = _CurrentRec.EmpName;
                        Temprec.EmpDept = _CurrentRec.EmpDept;
                    //How to create a clone of _CurrentRec here??

                    _CurrentRec.EmpName = _CurrentRec.EmpDept = "";
                    _CurrentRec.EmpId = value;
                    RaisePropertyChanged("CurrentRec");
                    _CurrentRec.EmpName = Temprec.EmpName;
                    _CurrentRec.EmpDept = Temprec.EmpDept;
                    _CurrentRec.EmpId = Temprec.EmpId;

                    if (_SearchFound == true)
                    {
                        _SearchFound = false;
                        RaisePropertyChanged("SearchFound");
                    }
                    Temprec = null;
                }

            }
        }
    }
    public void LoadData()
    {
        if (Employees == null) Employees = new ObservableCollection<Employee>();
       /* Employees.Add(new Employee { EmpId = "1", EmpName = "Justin", EmpDept = "Accounts" });
        Employees.Add(new Employee { EmpId = "2", EmpName = "Bill Gates", EmpDept = "Microsoft" });
        Employees.Add(new Employee { EmpId = "3", EmpName = "Steve", EmpDept = "Apple" });
        */

    }
}

EmployeeView.xaml

    <UserControl x:Class="MVVMDemo.Views.EmployeeView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:view="clr-namespace:MVVMDemo.ViewModel"
             xmlns:local="clr-namespace:MVVMDemo.Views"

             mc:Ignorable="d" 
             d:DesignHeight="120" d:DesignWidth="340">

    <!--<UserControl.DataContext>
        <view:EmployeeViewModel/>
    </UserControl.DataContext>-->

    <StackPanel>
        <WrapPanel>
            <Label Content="Empployee Id:"/>
            <TextBox x:Name="txtEmpId" Width="40" Height="22" Margin="64,0,5,0" Text="{Binding Path=EmpId,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"   />
            <Button Content="&lt;&lt;" x:Name="cmdBack" Height="20" Width="48" Click="cmdBack_Click" Margin="4,0,10,0"/>
            <Button Content="&gt;&gt;" x:Name="cmdfwd" Height="20" Width="48" Click="cmdfwd_Click"/>
        </WrapPanel>

        <WrapPanel>
            <Label Content="Empployee Name:"/>
            <TextBox x:Name="txtEmpName" Width="100" Height="22" Margin="43,0" Text="{Binding Path=CurrentRec.EmpName,Mode=TwoWay}" IsEnabled="{Binding SearchFound}"/>
        </WrapPanel>

        <WrapPanel>
            <Label Content="Empployee Department:"/>
            <TextBox x:Name="txtEmpDept" Width="100" Height="22" Margin="10,0" Text="{Binding Path=CurrentRec.EmpDept,Mode=TwoWay}" IsEnabled="{Binding SearchFound}"/>
        </WrapPanel>

    </StackPanel>
</UserControl>

EmployeeView.xaml.cs

 public partial class EmployeeView : UserControl
{

    public EmployeeView()
    {
        InitializeComponent();
        objGlobal = new ClsGlobal();
        EVM = objGlobal.EmpViewModel;
    }


    EmployeeViewModel EVM;
    ClsGlobal objGlobal;
    public int Current_Rec_Index = 0;

    private void cmdBack_Click(object sender, RoutedEventArgs e)
    {
        if (EVM.Employees.Count <= 0) return;
        Current_Rec_Index = Current_Rec_Index <= 0 ? EVM.Employees.Count - 1 : Current_Rec_Index-1;
        EVM.EmpId = (int.Parse(EVM.Employees[Current_Rec_Index].EmpId)).ToString();
        EVM.SearchFound = true;
        //RaisePropertyChanged("SearchFound");
    }

    private void cmdfwd_Click(object sender, RoutedEventArgs e)
    {
        if (EVM.Employees.Count <= 0) return;
        Current_Rec_Index = Current_Rec_Index >= EVM.Employees.Count-1 ? 0 : Current_Rec_Index+1;
        EVM.EmpId = (int.Parse(EVM.Employees[Current_Rec_Index].EmpId)).ToString();
        EVM.SearchFound = true;
    }
    protected void OnPropertyChanged(string name)
    {
        MessageBox.Show("aaa");
        //if(UpdateSourceTrigger.)
        // If UpdateSourceTrigger= PropetyChanged then process one way
        // If UpdateSourceTrigger= LostFocus then process one way
    }
}

EmployeeWindow.xaml

     <Window x:Class="MVVMDemo.EmployeeWindow"
        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:local="clr-namespace:MVVMDemo"
        xmlns:views="clr-namespace:MVVMDemo.Views"
        mc:Ignorable="d"
        Title="EmployeeWindow" Height="160" Width="340" Loaded="Window_Loaded" ResizeMode="NoResize">
    <Grid>
        <views:EmployeeView x:Name="empview"/>
        <Button x:Name="cmdAddNewRec" Content="Add" Click="cmdAddNewRec_Click" Height="20" Width="50" HorizontalAlignment="Left" Margin="71,89,0,11" IsEnabled="{Binding EVM.SearchFound}" />
        <Button x:Name="cmdDeleteRec" Content="Delete" Click="cmdDeleteRec_Click" Height="20" Width="50" HorizontalAlignment="Left" Margin="138,89,0,11" IsEnabled="{Binding EVM.SearchFound}" />
        <Button x:Name="cmdCancel" Content="Cancel" Click="cmdCancel_Click" Height="20" Width="50" HorizontalAlignment="Left" Margin="207,89,0,11" />
    </Grid>
</Window>

EmployeeWindow.xaml.cs

 public partial class EmployeeWindow : Window
{
    public EmployeeWindow()
    {
        InitializeComponent();
    }
    EmployeeViewModel EVM;
    ClsGlobal objGlobal;
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        objGlobal = new ClsGlobal();
        EVM = objGlobal.EmpViewModel;
        empview.DataContext = EVM;
    }

    Employee NewRec = null;

    private void cmdAddNewRec_Click(object sender, RoutedEventArgs e)
    {
        //How to disable this button using binding here,both using code behind as well as xaml??
        if (!EVM.SearchFound) return;
        NewRec = new Employee();
        NewRec.EmpId = (EVM.Employees.Count + 1).ToString();
        NewRec.EmpName = "";
        NewRec.EmpDept = "";
        EVM.Employees.Add(NewRec);
        EVM.EmpId = NewRec.EmpId;
        empview.Current_Rec_Index = 0;
        EVM.SearchFound = true;
    }

    private void cmdDeleteRec_Click(object sender, RoutedEventArgs e)
    {
        //How to disable this button using binding here,both using code behind as well as xaml??
        if (!EVM.SearchFound) return;
        EVM.Employees.Remove(EVM.CurrentRec);
        EVM.CurrentRec = EVM.Employees.FirstOrDefault();
        empview.Current_Rec_Index = 0;
    }

    private void cmdCancel_Click(object sender, RoutedEventArgs e)
    {
        if (EVM.CurrentRec.Equals(NewRec))
        {
            EVM.Employees.Remove(NewRec);
            EVM.CurrentRec = EVM.Employees.FirstOrDefault();
            empview.Current_Rec_Index = 0;
        }

    }
}
\$\endgroup\$

closed as off-topic by holroy, Graipher, alecxe, mdfst13, Raystafarian Apr 28 '17 at 17:18

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions containing broken code or asking for advice about code not yet written are off-topic, as the code is not ready for review. After the question has been edited to contain working code, we will consider reopening it." – holroy, Graipher, alecxe, mdfst13, Raystafarian
If this question can be reworded to fit the rules in the help center, please edit the question.

1
\$\begingroup\$

Several comments to your code in no particular order:

  1. Naming: a class Employee should have properties named Id, Name, Department. Adding prefixes really do not add anything but makes reading harder.
  2. Commands: agree with BCdotWEB, you should use commands.
  3. ViewModel: the ViewModel of a model tipically has the same properties as the model if they are required on the view so I expected fo find in the ViewModel EmpName and EmpDept.
  4. The EmployeeViewModel is not really the view model of the employee because it does not have employee properties but a Employee List

I would expect something like this:

public class Employee
{

    private string _id;
    public string Id
    {
        get
        {
            return _id;
        }
        set
        {
            _id = value;
        }
    }

    private string _name;
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }

    private string _department;
    public string Department
    {
        get
        {
            return _department;
        }
        set
        {
            _department = value;
        }
    }
}

class EmployeeViewModel
{
    private Employee _model;

    public string Id
    {
        get
        {
            return _model.Id;
        }
        set
        {
            if (_model.Id != value)
            {
                _model.Id = value;
                this.RaisePropertyChanged(...);
            }
        }
    }

    private string _name;
    public string Name
    {
        get
        {
            return _model.Name;
        }
        set
        {
            if (_model.Name != value)
            {
                _model.Name = value;
                this.RaisePropertyChanged(...);
            }
        }
    }

    private string _department;
    public string Department
    {
        get
        {
            return _model.Department;
        }
        set
        {
            if (_model.Department != value)
            {
                _model.Department = value;
                this.RaisePropertyChanged(...);
            }
        }
    }
}

Then there should be another class that contains the List of Employees which of course is not an employee and needs to be modeled.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.