代码之家  ›  专栏  ›  技术社区  ›  user3735822

为什么Mvvm方法不适用于我的计算器?

  •  0
  • user3735822  · 技术社区  · 12 年前

    我正在尝试使用silverlight 5处理MVVM,我的xaml代码如下:

     <Grid x:Name="LayoutRoot" Background="White" Height="100" Width="350">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
           <TextBox Grid.Column="0" Text="{Binding FirstValue, Mode=TwoWay}" Height="25" TextAlignment="Right"/>
            <TextBlock Grid.Column="1" Text="+" Height="25" TextAlignment="Center"/>
            <TextBox Grid.Column="2" Text="{Binding SecondValue, Mode=TwoWay}" Height="25" TextAlignment="Right"/>
            <TextBlock Grid.Column="3" Text="=" Height="25" TextAlignment="Center"/>
            <TextBlock Grid.Column="4" Text="{Binding Result, Mode=OneWay}" Height="25" TextAlignment="Left"/>
            <Button Grid.Row="1" Grid.ColumnSpan="5" Margin="0,5,0,0" Content="Calculate" Command="{Binding CalculateCommand}"  />
        </Grid>
    

    public MainPage()
            {
                InitializeComponent();
                this.DataContext = new CalculatorViewModel();
            }
    

    我的CalculatorViewModel.cs类是:

    public class CalculatorViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            public CalculatorModel cc;
    
    
            private string _firstValue;
            public string FirstValue
            {
                get { return _firstValue; }
                set
                {
                    _firstValue = value;
                    OnPropertyChanged("FirstValue");
                }
            }
    
            private string _secondValue;
            public string SecondValue
            {
                get { return _secondValue; }
                set
                {
                    _secondValue = value;
                    OnPropertyChanged("SecondValue");
                }
            }
    
            private string _result;
            public string Result
            {
                get { return _result; }
                private set
                {
                    _result = value;
                    OnPropertyChanged("Result");
                }
            }
    
            private ICommand _calculateCommand;
            public ICommand CalculateCommand
            {
                get { return _calculateCommand; }
            }
    
            public CalculatorViewModel()
            {
                cc = new CalculatorModel();
                cc.FirstValue = _firstValue;
                cc.SecondValue = _secondValue;
                cc.Result = _result;
                _calculateCommand = new RelayCommand(cc.Calculate) { IsEnabled = true };
                //This Calculate() is defined in Model class (CalculatorModel.cs).
             }    
    
            protected void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
                }
            }
    
        }
    

    我想在Model类(CalculatorModel.cs)中定义这个计算委托。( 如果我错了,请纠正我 ).

    我是这样做的:

     public class CalculatorModel
        {
            #region PROPERTIES
            public string FirstValue;
            public string SecondValue;
            public string Result;
    
            #endregion
            //CalculatorViewModel cv = new CalculatorViewModel();
    
            public CalculatorModel()
            {
                this.Result = "";
                this.FirstValue = "";
                this.SecondValue = "";              
            }
            public void Calculate()
            {
                MessageBox.Show("check : " +FirstValue);
                Result = (Convert.ToInt32(FirstValue) + Convert.ToInt32(SecondValue)).ToString();
            }
        }
    

    问题是我不知道 为什么调试Result、FirstValue和SecondValue的值为空 代表 calculate() 在单击按钮时调用,但结果中没有更新输出。

    有人能纠正我在Model类中定义calculate()的方法中的错误吗?

    1 回复  |  直到 12 年前
        1
  •  2
  •   Henk Holterman    12 年前

    您似乎没有更新模型中的值。数据绑定仅在View和ViewModel之间有效。

        private string _firstValue;
        public string FirstValue
        {
            get { return _firstValue; }
            set
            {
                _firstValue = value;
                cc.FirstValue = _firstValue;     // add this
                OnPropertyChanged("FirstValue");
            }
        }
    

    对SecondValue也是如此。更改命令,以便将结果指定给“结果”。

    这告诉您,您的设置不是最高效或最优雅的。 考虑

    1. 使模型INotifyPropertyChanged并绑定到Model.FirstValue
    2. 或者,在这里放弃模型的概念。

    当您使模型实现INPC时,您可以(应该)从VM中完全删除FirstValue、SecondValue和Result。您可以绑定到模型: Text="{Binding Path=cc.FirstValue, Mode=TwoWay}" 然后使模型成为属性:

       public CalculatorModel cc { get; set; }   // must be a property
    

    否则,“重复”属性的更好模式是:

        //private string _firstValue;
        public string FirstValue
        {
            get { return cc.FirstValue; }
            set
            {
                //_firstValue = value;
                cc.FirstValue = value;           // add this
                OnPropertyChanged("FirstValue");
            }
        }
    

    避免两次存储数据。