简体   繁体   English

简单计算器应用程序的按钮单击事件上的Cant更新屏幕(文本框)

[英]Cant update screen (textbox) on button click event for simple calculator application

Iam new to c# windows phone development and Iam attempting to build a simple calculator application using the mvvm design pattern. Iam是C#Windows Phone开发的新手,Iam尝试使用mvvm设计模式构建一个简单的计算器应用程序。 I have a model class currently with one string variable. 我有一个带有一个字符串变量的模型类。 this is bound to my calculator screen which is a textbox. 这绑定到我的计算器屏幕上,这是一个文本框。 I also have a number "1" button. 我也有一个数字“ 1”按钮。 when this is pressed, i want the textbox "screen" to update the value. 当按下此按钮时,我希望文本框“屏幕”更新该值。 this is done in a command class that implements ICommand interface. 这是在实现ICommand接口的命令类中完成的。 Unfortunately this isnt working currently and I cant figure out where the problem is. 不幸的是,这目前无法正常工作,我无法弄清楚问题出在哪里。 below is my model class. 下面是我的模型课。 its very basic. 它非常基本。

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));
        }
    } 

}

next is my xaml file for the mainpage. 接下来是主页的xaml文件。 currently i have the no. 目前我没有。 1 button linked to a command class execute() method. 1个链接到命令类execute()方法的按钮。 and my screen textbox has a binding to my Enteredvalue string. 并且我的屏幕文本框绑定了我的Enteredvalue字符串。 obviously this doesnt look like the ideal way to do it but iam learning it this way as its how some applications are being developed where iam doing an internship. 显然,这似乎不是理想的方法,但iam是以这种方式学习的,因为我是在iam做实习的地方开发某些应用程序的。

<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>

and finally I have the command class. 最后是命令类 the execute method appends the _enteredvalue string. execute方法附加_enteredvalue字符串。 which seems to work when debugging. 这似乎在调试时起作用。 my issue seems to be coming for the raisepropertychanged method being passed a null. 我的问题似乎是因为将属性传递给null的raisepropertychanged方法。 but iam not sure how to fix this. 但我不确定如何解决此问题。

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";
    }
 }
}

again i know this is a bit of a bastardisation of mvvm but iam trying to learn how its implemented where i work. 我再次知道这是mvvm的混蛋,但是iam试图了解它在我工作的地方是如何实现的。 any help is greatly appreciated. 任何帮助是极大的赞赏。

The thing that bothers me the most from your current implementation of MVVM is the Command. 从您当前的MVVM实现中最令我困扰的是Command。 Basically we only need to create one class that implements ICommand. 基本上,我们只需要创建一个实现ICommand的类即可。 Then we can create multiple properties from that class, each can execute different methods/codes. 然后,我们可以从该类创建多个属性,每个属性都可以执行不同的方法/代码。 Example implementation of ICommand from another SO post : 来自另一个SO帖子的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;
}

Then we usually put command properties mentioned above in the ViewModel: 然后我们通常将上面提到的命令属性放在ViewModel中:

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

Assuming Page's DataContext has been set properly to Sum , we can bind the button to Command property in Sum as follows: 假设页面的DataContext的已正确设置为Sum ,我们可以绑定的按钮,即可命令属性Sum ,如下所示:

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

Some tutorials on getting started with MVVM in Windows Phone application: 有关Windows Phone应用程序中MVVM入门的一些教程:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM