2017-02-08 8 views
-1

У меня есть две учетных закладок UserControls и TabLayout. Заработная плата содержит ToolBar и TabControl, а TabLayout содержит Grid. TabItems для TabControl в Payroll заполняются TabLayout через ObservableCollection в моем MainViewModel.wpf - Предотвращение дублирования информации MVVM

Около часа назад я задал этот вопрос: WPF Unable to retrieve binding values MVVM и получил его.

Теперь я столкнулся с проблемой, когда, поскольку ViewModel теперь является единственным экземпляром, информация в одной вкладке переносится на другую. Поэтому все вкладки показывают одно и то же.

Если я создаю новый экземпляр ViewModel для каждой вкладки, я больше не смогу получить значения привязки.

MainViewModel:

namespace OcelotPayroll.ViewModel 
{ 
    public class MainViewModel : ViewModelBase 
    {  
     public ObservableCollection<WorkspaceViewModel> Workspaces { get; set; }    

     public MainViewModel() 
     { 
      Workspaces = new ObservableCollection<WorkspaceViewModel>(); 
     } 


     private DelegateCommand _newWorkspaceCommand; 
     public ICommand NewWorkspaceCommand 
     { 
      get { return _newWorkspaceCommand ?? (_newWorkspaceCommand = new DelegateCommand(NewWorkspace)); } 
     } 

     private void NewWorkspace() 
     { 

      var workspace = new WorkspaceViewModel 
      { 
       LoadedControl = new TabLayout() { DataContext = this } 
      }; 
      Workspaces.Add(workspace); 
      SelectedIndex = Workspaces.IndexOf(workspace); 
     } 
    } 
} 

Расчет заработной платы DataContext устанавливается:

public Payroll() 
    { 
     InitializeComponent(); 
     DataContext = new PayslipModel(); 
    } 

PayslipModel/ВМ:

namespace OcelotPayroll 
{ 
    public class PayslipModel : EmployeeModel 
    {  
     private decimal _amount; 

     public decimal Amount 
     { 
      get 
      { 
       return _amount; 
      } 
      set 
      { 
       _amount = value; 
       OnPropertyChanged("Amount"); 
      } 
     } 

     public string NisName 
     { 
      get 
      { 
       return _nis; 
      } 
      set 
      { 
       _nis = value; 
       OnPropertyChanged("NisName"); 
      } 
     } 

     public string EdTaxName 
     { 
      get 
      { 
       return _edtax; 
      } 
      set 
      { 
       _edtax = value; 
       OnPropertyChanged(); 
      } 
     } 

     public string NhtName 
     { 
      get 
      { 
       return _nht; 
      } 
      set 
      { 
       _nht = value; 
       OnPropertyChanged(); 
      } 
     } 

     public string PayeName 
     { 
      get 
      { 
       return _paye; 
      } 
      set 
      { 
       _paye = value; 
       OnPropertyChanged(); 
      } 
     } 

     public string NisVal 
     { 
      get 
      { 
       return _nisVal; 
      } 
      set 
      { 
       _nisVal = value; 
       OnPropertyChanged(); 
      } 
     } 

     public string EdTaxVal 
     { 
      get 
      { 
       return _edVal; 
      } 
      set 
      { 
       _edVal = value; 
       OnPropertyChanged(); 
      } 
     } 

     public string NhtVal 
     { 
      get 
      { 
       return _nhtVal; 
      } 
      set 
      { 
       _nhtVal = value; 
       OnPropertyChanged(); 
      } 
     } 

     public string PayeVal 
     { 
      get 
      { 
       return _payeVal; 
      } 
      set 
      { 
       _payeVal = value; 
       OnPropertyChanged(); 
      } 
     } 

     public decimal StautoryIncome 
     { 
      get 
      { 
       return statIncome; 
      } 
      set 
      { 
       statIncome = value; 
      } 
     } 

     public string TotalDeduction 
     { 
      get 
      { 
       return totalDed; 
      } 
      set 
      { 
       totalDed = value; 
       OnPropertyChanged(); 
      } 
     } 

     public string NetPay 
     { 
      get 
      { 
       return _netpay; 
      } 
      set 
      { 
       _netpay = value; 
       OnPropertyChanged(); 
      } 
     } 

     public bool NisChecked 
     { 
      get 
      { 
       return nisIsChecked; 
      } 
      set 
      { 
       nisIsChecked = value; 

       OnPropertyChanged("NisChecked"); 

       CalcNis(); 
      } 
     } 

     public bool EdTaxChecked 
     { 
      get 
      { 
       return edtaxIsChecked; 
      } 
      set 
      { 
       edtaxIsChecked = value; 
       OnPropertyChanged(); 
       CalcEdTax(); 
      } 
     } 

     public bool NhtChecked 
     { 
      get 
      { 
       return nhtIsChecked; 
      } 
      set 
      { 
       nhtIsChecked = value; 
       OnPropertyChanged(); 
       CalcNht(); 
      } 
     } 

     public bool PayeChecked 
     { 
      get 
      { 
       return payeIsChecked; 
      } 
      set 
      { 
       payeIsChecked = value; 
       OnPropertyChanged(); 
       CalcPaye(); 
      } 
     } 

     public bool LevyChecked 
     { 
      get 
      { 
       return levyIsChecked; 
      } 
      set 
      { 
       levyIsChecked = value; 
       OnPropertyChanged(); 
       CalcLevy(); 
      } 
     } 

     public bool WeeklyChecked 
     { 
      get 
      { 
       return wklyIsChecked; 
      } 
      set 
      { 
       wklyIsChecked = value; 
       OnPropertyChanged(); 
      } 
     } 

     public bool FnChecked 
     { 
      get 
      { 
       return fnIsChecked; 
      } 
      set 
      { 
       if (fnIsChecked == value) 
        return; 

       fnIsChecked = value; 
       OnPropertyChanged(); 
      } 
     } 
     public bool MonthlyChecked 
     { 
      get 
      { 
       return monthlyIsChecked; 
      } 
      set 
      { 
       if (monthlyIsChecked == value) 
        return; 

       monthlyIsChecked = value; 
       OnPropertyChanged(); 
      } 
     } 

     private DateTime _date; 
     public DateTime Date 
     { 
      get 
      { 
       return _date; 

      } 
      set 
      { 
       _date = value; 
      } 
     } 

     private string _annualGross; 

     public string AnnualGross 
     { 
      get 
      { 
       return _annualGross; 
      } 
      set 
      { 
       _annualGross = value; 
       OnPropertyChanged(); 
      } 
     } 

     private string _annualNis; 

     public string AnnualNis 
     { 
      get 
      { 
       return _annualNis; 
      } 
      set 
      { 
       _annualNis = value; 
       OnPropertyChanged(); 
      } 
     } 

     private string _annualNht; 

     public string AnnualNht 
     { 
      get 
      { 
       return _annualNht; 
      } 
      set 
      { 
       _annualNht = value; 
       OnPropertyChanged(); 
      } 
     } 

     private string _annualEdtax; 

     public string AnnualEdTax 
     { 
      get 
      { 
       return _annualEdtax; 
      } 
      set 
      { 
       _annualEdtax = value; 
       OnPropertyChanged(); 
      } 
     } 

     private string _annualPaye; 

     public string AnnualPaye 
     { 
      get 
      { 
       return _annualPaye; 
      } 
      set 
      { 
       _annualPaye = value; 
       OnPropertyChanged(); 
      } 
     } 

     public PayslipModel() 
     {  
      Date = DateTime.Today.Date; 

      SelectAll = new DelegateCommand(Select,() => CanSelect); 

      UnSelectAll = new DelegateCommand(UnSelect,() => CanUnSelect); 

      SaveToDatabase = new DelegateCommand(Save,() => CanSave); 

      scon = new MichaelAllenEntities(); 

     } 

     public ICommand SelectAll 
     { 
      get; set; 
     } 

     private bool CanSelect 
     { 
      get { return Hide1 = true; } 
     } 

     private void Select() 
     { 
      if (Hide1 == true) 
      { 
       NisChecked = true; 
       EdTaxChecked = true; 
       NhtChecked = true; 
       PayeChecked = true; 
      } 
     } 

     public ICommand UnSelectAll 
     { 
      get; set; 
     } 

     private bool CanUnSelect 
     { 
      get { return Hide1 = true; } 
     } 

     private void UnSelect() 
     { 
      if (Hide1 == true) 
      { 
       NisChecked = false; 
       EdTaxChecked = false; 
       NhtChecked = false; 
       PayeChecked = false; 
      } 
     } 

     public ICommand SaveToDatabase 
     { 
      get; set; 
     } 

     private bool CanSave 
     { 
      get { return Workspaces.Count > 0; } 
     }  

     private async void Save() 
     { 
      try 
      { 
       var salary = new SalaryInfo 
       { 
        EmpId = SelectedEmployee.EmpId, 
        EmpName = SelectedEmployee.EmpName, 
        NIS = decimal.Parse(NisVal.ToString()), 
        NHT = decimal.Parse(NhtVal.ToString()), 
        EdTax = decimal.Parse(EdTaxVal.ToString()), 
        PAYE = decimal.Parse(PayeVal.ToString()), 
        TotalTax = decimal.Parse(TotalDeduction.ToString()), 
        StatutoryIncome = StautoryIncome, 
        GrossPay = Amount, 
        NetPay = decimal.Parse(NetPay.ToString()), 
        Date = Date, 
        Earnings = Earnings, 
        PayPeriod = SelectedValueOne.Value 
       }; 
       scon.SalaryInfoes.Add(salary); 
       scon.SaveChanges(); 
      } 
      catch (DbEntityValidationException ex) 
      { 

      } 
      catch(Exception ex) 
      { 
       var exceptionDialog = new MessageDialog 
       { 
        Message = { Text = string.Format("{0}", ex) } 
       }; 

       await DialogHost.Show(exceptionDialog, "RootDialog"); 
      } 

     } 

     private bool _hide1 = true; 

     public bool Hide1 
     { 
      get 
      { 
       return _hide1; 
      } 
      set 
      { 
       _hide1 = value; 
       OnPropertyChanged(); 
      } 
     } 

     private bool _hide2 = false; 

     public bool Hide2 
     { 
      get 
      { 
       return _hide2; 
      } 
      set 
      { 
       _hide2 = value; 
       OnPropertyChanged(); 
      } 
     } 

     private EmployeeInfo _selectedEmployee; 

     public new EmployeeInfo SelectedEmployee 
     { 
      get { return _selectedEmployee; } 
      set 
      { 
       _selectedEmployee = value; 
       OnPropertyChanged(); 

       if(SelectedEmployee.EmployedUnder == "Michael Allen") 
       { 
        Hide1 = true; 
        Hide2 = false; 
       } 
       if(SelectedEmployee.EmployedUnder == "Barachel Ltd") 
       { 
        Hide2 = true; 
        Hide1 = false; 
       } 
      } 
     } 

     private string _hours; 

     public string Hours 
     { 
      get 
      { 
       return _hours; 
      } 
      set 
      { 
       _hours = value; 
       OnPropertyChanged(); 
      } 
     } 

     private string _rate; 

     public string Rate 
     { 
      get 
      { 
       return _rate; 
      } 
      set 
      { 
       _rate = value; 
       OnPropertyChanged(); 
       if (Rate != string.Empty || Hours != string.Empty) 
       { 
        Amount = decimal.Parse((double.Parse(Hours.ToString()) * double.Parse(Rate.ToString())).ToString()); 
       }else 
       { 
        Amount = 0; 
       } 
      } 
     } 

     private string _selectedDate; 

     public string SelectedDate 
     { 
      get 
      { 
       return _selectedDate; 
      } 
      set 
      { 
       _selectedDate = value; 
       OnPropertyChanged(); 
      } 
     } 

     private string _earnings; 

     public string Earnings 
     { 
      get 
      { 
       return _earnings; 
      } 
      set 
      { 
       _earnings = value; 
       OnPropertyChanged(); 
      } 
     } 

     #region Calculations 

     public async void CalcNis() 
     { 
      try 
      { 
       float nis = 0; 

       NisName = "N.I.S."; 

       SqlConnection con = new SqlConnection(scon.Database.Connection.ConnectionString); 
       con.Open(); 
       SqlCommand cmd = new SqlCommand("select NIS from Deductions where TaxId='1'", con); 

       SqlDataReader sdr = cmd.ExecuteReader(); 
       while (sdr.Read()) 
       { 
        nis = float.Parse(sdr.GetValue(0).ToString()); 
       } 

       con.Close(); 

       if (Amount != 0) 
       { 
        NisVal = (decimal.Parse(Amount.ToString()) * decimal.Parse(nis.ToString())).ToString("N2"); 
        StautoryIncome = (decimal.Parse(Amount.ToString()) - decimal.Parse(NisVal.ToString())); 
       } 
      } 
      catch(Exception ex) 
      { 
       var exceptionDialog = new MessageDialog 
       { 
        Message = { Text = ex.ToString() } 
       }; 

       await DialogHost.Show(exceptionDialog, "RootDialog"); 
      } 
     } 

     public async void CalcLevy() 
     { 
      try 
      { 
       if(LevyChecked == true) 
       { 
        float levy = 0; 

        NisName = "Contractor's Levy"; 

        SqlConnection con = new SqlConnection(scon.Database.Connection.ConnectionString); 
        con.Open(); 
        SqlCommand cmd = new SqlCommand("select ContractorLevy from Deductions where TaxId='1'", con); 

        SqlDataReader sdr = cmd.ExecuteReader(); 
        while (sdr.Read()) 
        { 
         levy = float.Parse(sdr.GetValue(0).ToString()); 
        } 

        con.Close(); 

        if (Amount != 0) 
        { 

         NisVal = (double.Parse(Amount.ToString()) * double.Parse(levy.ToString())).ToString("N2"); 

         TotalDeduction = double.Parse(NisVal.ToString()).ToString("N2"); 

         NetPay = (double.Parse(Amount.ToString()) - double.Parse(NisVal.ToString())).ToString("N2"); 
        } 
       }else 
        if(LevyChecked == false) 
       { 
        NisVal = string.Empty; 
        TotalDeduction = string.Empty; 
        NetPay = string.Empty; 
       } 
      } 
      catch (Exception ex) 
      { 
       var exceptionDialog = new MessageDialog 
       { 
        Message = { Text = ex.ToString() } 
       }; 

       await DialogHost.Show(exceptionDialog, "RootDialog"); 
      } 
     } 

     public async void CalcEdTax() 
     { 
      try 
      { 
       float edtax = 0; 

       EdTaxName = "EDUCATION TAX"; 

       SqlConnection con = new SqlConnection(scon.Database.Connection.ConnectionString); 
       con.Open(); 
       SqlCommand cmd = new SqlCommand("select EdTax from Deductions where TaxId='1'", con); 

       SqlDataReader sdr = cmd.ExecuteReader(); 
       while (sdr.Read()) 
       { 
        edtax = float.Parse(sdr.GetValue(0).ToString()); 
       } 

       con.Close(); 

       if (EdTaxName != string.Empty) 
       { 
        if (StautoryIncome != 0) 
        { 
         EdTaxVal = (statIncome * decimal.Parse(edtax.ToString())).ToString("N2"); 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       var exceptionDialog = new MessageDialog 
       { 
        Message = { Text = ex.ToString() } 
       }; 

       await DialogHost.Show(exceptionDialog, "RootDialog"); 
      } 
     } 

     public async void CalcNht() 
     { 
      try 
      { 
       float nht = 0; 

       NhtName = "N.H.T."; 

       SqlConnection con = new SqlConnection(scon.Database.Connection.ConnectionString); 
       con.Open(); 
       SqlCommand cmd = new SqlCommand("select NHT from Deductions where TaxId='1'", con); 

       SqlDataReader sdr = cmd.ExecuteReader(); 
       while (sdr.Read()) 
       { 
        nht = float.Parse(sdr.GetValue(0).ToString()); 
       } 

       con.Close(); 

       if (Amount != 0) 
       { 
        NhtVal = (decimal.Parse(Amount.ToString()) * decimal.Parse(nht.ToString())).ToString("N2"); 
       } 
      } 
      catch (Exception ex) 
      { 
       var exceptionDialog = new MessageDialog 
       { 
        Message = { Text = ex.ToString() } 
       }; 

       await DialogHost.Show(exceptionDialog, "RootDialog"); 
      } 
     } 

     private decimal _totalAmount; 

     public decimal TotalAmount 
     { 
      get 
      { 
       return _totalAmount; 
      } 
      set 
      { 
       _totalAmount = value; 
       OnPropertyChanged(); 
      } 
     } 

     public async void CalcPaye() 
     { 
      try 
      { 
       float paye = 0; 
       decimal threshold = 0, taxable = 0, above = 0.3M; 

       if (PayeChecked == true) 
       { 
        PayeName = "P.A.Y.E."; 

        SqlConnection con = new SqlConnection(scon.Database.Connection.ConnectionString); 
        con.Open(); 
        SqlCommand cmd = new SqlCommand("select PAYE, FNTaxThreshold from Deductions where TaxId='1'", con); 

        SqlDataReader sdr = cmd.ExecuteReader(); 

        if (Amount != 0) 
        { 
         while (sdr.Read()) 
         { 
          paye = float.Parse(sdr.GetValue(0).ToString()); 
          threshold = decimal.Parse(sdr.GetValue(1).ToString()); 
         } 

         con.Close(); 

         // 
         //Fortnightly 
         // 
         if (FnChecked == true) 
         { 

          if (threshold <= decimal.Parse(Amount.ToString())) 
          { 
           if ((double.Parse(Amount.ToString()) * 2) * 12 <= 796536) 
           { 
            taxable = StautoryIncome - threshold; 
            PayeVal = (taxable * 0).ToString("N2"); 
           } 
           else if ((double.Parse(Amount.ToString()) * 2) * 12 >= 796536 && (double.Parse(Amount.ToString()) * 2) * 12 <= 6000000) 
           { 
            taxable = StautoryIncome - threshold; 
            PayeVal = (taxable * decimal.Parse(paye.ToString())).ToString("N2"); 
           } 
           else if ((double.Parse(Amount.ToString()) * 2) * 12 > 6000000) 
           { 
            taxable = StautoryIncome - threshold; 
            PayeVal = (taxable * above).ToString("N2"); 
           } 

          } 
         } 

         // 
         //Monthly Checked 
         // 
         if (MonthlyChecked == true) 
         { 
          con.Open(); 

          cmd = new SqlCommand("select MonthlyThreshold from Deductions where TaxId='1'", con); 
          sdr = cmd.ExecuteReader(); 

          while (sdr.Read()) 
          { 
           threshold = decimal.Parse(sdr.GetValue(0).ToString()); 
          } 

          con.Close(); 

          if (threshold <= decimal.Parse(Amount.ToString())) 
          { 
           if ((double.Parse(Amount.ToString()) * 2) * 12 <= 796536) 
           { 
            taxable = StautoryIncome - threshold; 
            PayeVal = (taxable * 0).ToString("N2"); 
           } 
           else if ((double.Parse(Amount.ToString()) * 2) * 12 >= 796536 && (double.Parse(Amount.ToString()) * 2) * 12 <= 6000000) 
           { 
            taxable = StautoryIncome - threshold; 
            PayeVal = (taxable * decimal.Parse(paye.ToString())).ToString("N2"); 
           } 
           else if ((double.Parse(Amount.ToString()) * 2) * 12 > 6000000) 
           { 
            taxable = StautoryIncome - threshold; 
            PayeVal = (taxable * above).ToString("N2"); 
           } 

          } 
          else if (threshold > decimal.Parse(Amount.ToString())) 
          { 
           PayeVal = (0).ToString("N2"); 
          } 
         } 

        } 

        if (EdTaxVal != string.Empty || NhtVal != string.Empty || NisVal != string.Empty || PayeVal != string.Empty) 
        { 
         double total = 0; 


         total = double.Parse(NisVal.ToString()) + double.Parse(PayeVal.ToString()) + double.Parse(NhtVal.ToString()) + double.Parse(EdTaxVal.ToString()); 

         TotalDeduction = total.ToString("N2"); 

         NetPay = (double.Parse(Amount.ToString()) - total).ToString("N2"); 
        } 
       } 
       else if(PayeChecked == false) 
       { 
        if (PayeVal != string.Empty) 
        { 
         PayeName = string.Empty; 
         taxable += decimal.Parse(PayeVal.ToString()); 
         StautoryIncome += taxable; 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       var exceptionDialog = new MessageDialog 
       { 
        Message = { Text = ex.ToString() } 
       }; 

       await DialogHost.Show(exceptionDialog, "RootDialog"); 
      } 
     } 

     #endregion 
    } 
} 
+0

MVVM предназначен для отдельного интерфейса и слоев данных, и вы посмотрите, как вы их объединения. У меня нет времени, чтобы написать полный ответ + пример сейчас, но вы можете увидеть пример того, как MVVM используется в структуре TabControl [здесь] (https://rachel53461.wordpress.com/2011/12/18/ навигационно-с-MVVM-2 /). Единственное место, которое я когда-либо ожидал увидеть набор DataContext, - это первоначальная привязка для запуска приложения. В другом месте меня посылают красные предупреждающие флаги. – Rachel

+0

@Rachel, пример, который вы предоставили, на самом деле не то, что я ищу, и вы правы в DataContext. Я удалил его сейчас – bruh1234

ответ

0

Вы можете использовать шаблон ViewModelLocator, чтобы решить эту проблему. В основном этот шаблон состоит из класса, который имеет все необходимые свойства DataContext как Property. Это может быть статичным. И вам не нужно устанавливать DataContext в CodeBehind, вы можете установить в XAML ресурсы.

См: First
Second

0

Если вы хотите, чтобы вкладки отображали разные значения, вам, очевидно, нужно создать новый экземпляр вашего класса для каждого созданного вами TabLayout. Вы можете скопировать свойство значения так или иначе:

var workspace = new WorkspaceViewModel 
{ 
    LoadedControl = new TabLayout() { DataContext = new PayslipModel() { Amount = this.Amount, NisName = this.NisName, /* and so on for each property ... */} } 
}; 

Вы не можете установить DataContext всех элементов в той же инстанции.

+0

Отчасти это проблема, 'NewWorkspace()' хранится в MainViewModel, а PayslipModel - это отдельная ViewModel, которая имеет дело с тем, что отображается на вкладках. Таким образом, я не могу скопировать свойства, как вы предложили. Если есть намного лучший способ обработки вкладок в MVVM, которые вы можете предложить, я попытаюсь, то я не против :) – bruh1234

+0

Если вы не думаете, что кто-то сможет угадать, как выглядит ваш код, и что отношения между вашими типами и вы все еще хотите вас, вы должны действительно прочитать это: http://stackoverflow.com/help/mcve – mm8

+0

Я обновил вопрос. Так же, как и примечание, UserControl Payroll является дочерним элементом MainWindow, поэтому он называется «», а TabLayout будет дочерним элементом Payroll, то есть когда он добавляется в Workspace. – bruh1234