2017-06-16 35 views
1

對於使用MVVM的WPF編碼來說很新穎。嘗試使用MVVM在WPF中製作一個簡單的計算器。但無法在下面的代碼中觸發Icommand。如果可以的話,可以在這裏幫助我。感謝有人能幫助我。
查看代碼:無法在下面的代碼中正確使用MVVM /綁定,並且遇到Icommand屬性問題

<Window x:Class="MVVMCalculator.MainWindow" 
     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:MVVMCalculator" 
     mc:Ignorable="d" 
     Title="Calculator" Height="350" Width="300"> 

    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="85"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 
     <TextBox Text="{Binding Display, Mode=OneWay}" IsReadOnly="True" TextWrapping="Wrap" 
       Grid.Row="0" Background="#E2E2E2" Margin="0,10,0,0" VerticalAlignment="Top" 
       Height="75" Width="250" HorizontalAlignment="Center" FontSize="22" FontWeight="Bold" 
       TextAlignment="Right"> 
      <TextBox.Effect> 
       <DropShadowEffect/> 
      </TextBox.Effect> 
     </TextBox> 
     <ItemsControl Grid.Row="1" ItemsSource="{Binding Buttns}" Margin="15,15,15,10"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <UniformGrid Columns="5" Rows="4" /> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <Button Content="{Binding Txt, Mode=TwoWay}" Command="{Binding Enter_number}" 

          FontSize="18" FontWeight="Bold" Height="50" Width="50" Background="#eef2f3" 
          BorderBrush="Black" BorderThickness="1.0" Name="number"> 
         <Button.Effect> 
          <DropShadowEffect/> 
         </Button.Effect> 
        </Button> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </Grid> 
</Window> 

視圖模型代碼:

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Input; 

namespace MVVMCalculator 
{ 
    class ViewModel : INotifyPropertyChanged 
    { 
     Buttons btn = new Buttons(); 
     private decimal operand1; 
     private decimal operand2; 
     private string operation; 
     private decimal result; 
     private string display; 
     private bool newDisplayRequired = false; 
     ObservableCollection<Buttons> buttns; 
     public ObservableCollection<Buttons> Buttns 
     { 
      get { return buttns; } 
      set { buttns = value; } 
     } 
     public decimal Result 
     { 
      get { return result; } 
     } 
     public decimal Operand1 
     { 
      get { return operand1; } 
      set { operand1 = value; } 
     } 
     public decimal Operand2 
     { 
      get { return operand2; } 
      set { operand2 = value; } 
     } 
     public string Operation 
     { 
      get { return operation; } 
      set { operation = value; } 
     } 
     public string Display 
     { 
      get { return display; } 
      set { display = value; 
       OnPropertyChanged("Display"); 
      } 
     } 

     public ViewModel() 
     { 
      buttns = new ObservableCollection<Buttons> 
      { 
       new Buttons("1"), new Buttons("2"), new Buttons("3"), 
       new Buttons("C"), new Buttons("Back"), new Buttons("4"), 
       new Buttons("5"), new Buttons("6"), new Buttons("CE"), 
       new Buttons("%"), new Buttons("7"), new Buttons("8"), 
       new Buttons("9"), new Buttons("/"), new Buttons("*"), 
       new Buttons("0"), new Buttons("."), new Buttons("+"), 
       new Buttons("-"), new Buttons("=") 
      }; 
      display = "0"; 
      operand1 = 0; 
      operand2 = 0; 
      operation = ""; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void OnPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     private ICommand enter_number; 
     public ICommand Enter_number 
     { 
      get 
      { 
       if(enter_number==null) 
       { 
        enter_number = new DelegateCommand<string>(MyAction, _canExecute); 
       } 
       return enter_number; 
      } 
     } 
     private static bool _canExecute(string button) 
     { 
      return true; 
     } 
     public void MyAction(string btn) 
     { 
      switch(btn) 
      { 
       case "C": 
        display = "0"; 
        operand1 = 0; 
        operand2 = 0; 
        //operation = ""; 
        break; 
       case ".": 
        if (!display.Contains(".")) 
        { 
         Display = display + "."; 
        } 
        break; 
       case "Back": 
        if (display.Length > 1) 
         Display = display.Substring(0, display.Length - 1); 
        else Display = "0"; 
        break; 
       default: 
        if (display == "0" || newDisplayRequired) 
         Display = btn; 
        else 
         Display = display + btn; 
        break; 
      } 
     } 
    } 
} 

按鈕類:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace MVVMCalculator 
{ 
    class Buttons:INotifyPropertyChanged 
    { 
     private string txt; 
     public string Txt 
     { 
      get { return txt; } 
      set { txt = value; } 
     } 

     public Buttons(string a) 
     { 
      txt = a; 
     } 

     public Buttons() 
     { 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void OnPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
} 

Xaml.cs:

using System; 
using System.Collections.Generic; 
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.Navigation; 
using System.Windows.Shapes; 

namespace MVVMCalculator 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = new ViewModel(); 
     } 
    } 
} 
+0

請詳細描述您的問題。 –

+0

當我運行時,我可以看到它上面有按鈕的UI,我可以調試程序直到那裏,但是當我點擊任何按鈕時,我無法調試程序,也沒有任何改變,我可以看到。可能,我的命令有問題! – Renee

+0

當你設置公共'Display'時,你正在設置私人'display',這將觸發UI變化。但是,這僅適用於字符串爲「C」的情況。 – XAMlMAX

回答

0

由於Enter_number屬性在ViewModel類中定義你需要使用一個{RelativeSource}能夠綁定到它:

<Button Content="{Binding Txt, Mode=TwoWay}" 
      Command="{Binding DataContext.Enter_number, RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
      FontSize="18" FontWeight="Bold" Height="50" Width="50" Background="#eef2f3" 
      BorderBrush="Black" BorderThickness="1.0" Name="number"> 
     <Button.Effect> 
      <DropShadowEffect/> 
     </Button.Effect> 
    </Button> 

默認的ButtonDataContextItemsSource收集ItemsControl在當前Buttons對象,這就是爲什麼你的綁定失敗。

+0

非常感謝你的時間和建議。我已將其標記爲答案。你可以請我路由到鏈接,我可以學習從UI到源的數據綁定。 – Renee

+0

請參考以下文章:http://www.c-sharpcorner.com/UploadFile/yougerthen/relativesources-in-wpf/ – mm8

相關問題