无法在按钮点击事件上更新屏幕(文本框)以进行简单的计算器应用

时间:2014-02-01 12:27:04

标签: c# mvvm windows-phone-8

我刚接触c#windows phone开发,Iam尝试使用mvvm设计模式构建一个简单的计算器应用程序。我有一个模型类,目前有一个字符串变量。这是绑定到我的计算器屏幕,这是一个文本框。我还有一个数字“1”按钮。当按下它时,我希望文本框“屏幕”更新值。这是在一个实现ICommand接口的命令类中完成的。不幸的是,目前还没有工作,我无法找出问题所在。下面是我的模特课。它非常基本。

namespace PhoneApp2.model
{
public class Sum : INotifyPropertyChanged
{

    private string _enteredVal;


    public string EnteredVal
    {
        get { return _enteredVal ; }
        set
        {
            _enteredVal = value;
            RaisePropertyChanged("EnteredVal");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged(string propName)
    {
      if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    } 

}

接下来是我的主页的xaml文件。目前我有没有。 1个按钮链接到命令类execute()方法。我的屏幕文本框与我的Enteredvalue字符串绑定。显然,这看起来并不像是理想的方式,但我学习它的方式就像我正在开展实习的一些应用程序一样。

<Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.Resources>
            <commands:UpdateScreenCommand x:Key="myCommand"/>
        </Grid.Resources>

            <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            </Grid.RowDefinitions>


           <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="Calculator" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>

           </StackPanel>

           <!--ContentPanel - place additional content here-->
           <Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,143,0,0" >
           <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>

            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
            </Grid.ColumnDefinitions>

            <Button Content="1"   Command="{StaticResource myCommand}"   CommandParameter="{Binding}" Height="Auto" Width="Auto" Grid.Row="0" Grid.Column="0"/>
            <Button Content="2"   Height="Auto" Width="Auto" Grid.Row="0" Grid.Column="1"/>
            <Button Content="3"   Height="Auto" Width="Auto" Grid.Row="0" Grid.Column="2"/>
            <Button Content="+"   Height="Auto" Width="Auto" Grid.Row="0" Grid.Column="3"/>
            <Button Content="4"   Height="Auto" Width="Auto" Grid.Row="1" Grid.Column="0"/>
            <Button Content="5"   Height="Auto" Width="Auto" Grid.Row="1" Grid.Column="1"/>
            <Button Content="6"   Height="Auto" Width="Auto" Grid.Row="1" Grid.Column="2"/>
            <Button Content="-"   Height="Auto" Width="Auto" Grid.Row="1" Grid.Column="3"/>
            <Button Content="7"   Height="Auto" Width="Auto" Grid.Row="2" Grid.Column="0"/>
            <Button Content="8"   Height="Auto" Width="Auto" Grid.Row="2" Grid.Column="1"/>
            <Button Content="9"   Height="Auto" Width="Auto" Grid.Row="2" Grid.Column="2"/>
            <Button Content="/"   Height="Auto" Width="Auto" Grid.Row="2" Grid.Column="3"/>
            <Button Content="0"   Height="Auto" Width="Auto" Grid.Row="3" Grid.Column="1"/>
            <Button Content="*"   Height="Auto" Width="Auto" Grid.Row="3" Grid.Column="3"/>
            <Button Content="C"   Height="Auto" Width="Auto" Grid.Row="3" Grid.Column="0"/>
            <Button Content="="   Height="Auto" Width="Auto" Grid.Row="3" Grid.Column="2"/>
           </Grid>
           <Grid  MinHeight="107" Margin="10,10,0,0" Grid.Row="1" VerticalAlignment="Top"     Width="458" RenderTransformOrigin="0.467,-0.089">
            <TextBox Height="Auto"  Text="{Binding EnteredValue, Mode=OneWay}" TextWrapping="Wrap"  VerticalAlignment="Center" Width="Auto" />
           </Grid>


           </Grid>

最后我有命令类。 execute方法追加_enteredvalue字符串。这在调试时似乎有用。我的问题似乎是将raisepropertychanged方法传递给null。但我不确定如何解决这个问题。

namespace PhoneApp2.commands
{
public class UpdateScreenCommand : ICommand
{
    public bool CanExecute(object parameter)
    {
        var m = (Sum) parameter;
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
         var m = (Sum) parameter;
         m.EnteredVal += "1";
    }
 }
}

我再次知道这是对mvvm的一种混蛋,但我试图了解它是如何在我工作的地方实现的。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

从当前MVVM实现中最让我烦恼的是命令。基本上我们只需要创建一个实现ICommand的类。然后我们可以从该类创建多个属性,每个属性可以执行不同的方法/代码。来自another SO post的ICommand的示例实现:

public class ActionCommand : ICommand
{
    private readonly Action _action;

    public ActionCommand(Action action)
    {
        _action = action;
    }

    public void Execute(object parameter)
    {
        _action();
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;
}

然后我们通常将上面提到的命令属性放在ViewModel中:

public class Sum : INotifyPropertyChanged
{   
    private ICommand _addOneCommand;
    public ICommand AddOneCommand
    {
        get 
        {
            return _addOneCommand
                ?? (_addOneCommand = new ActionCommand(() => 
                {
                    EnteredVal += "1";
                }));
        }
    }
    .....
    .....
}

假设Page的DataContext已正确设置为Sum,我们可以将按钮绑定到Sum中的Command属性,如下所示:

<Button Content="1" Command="{AddOneCommand}" Height="Auto" Width="Auto" Grid.Row="0" Grid.Column="0"/>

有关Windows Phone应用程序中MVVM入门的一些教程: