简体   繁体   中英

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. 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. when this is pressed, i want the textbox "screen" to update the value. this is done in a command class that implements ICommand interface. 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. currently i have the no. 1 button linked to a command class execute() method. and my screen textbox has a binding to my Enteredvalue string. 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.

<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. which seems to work when debugging. my issue seems to be coming for the raisepropertychanged method being passed a null. 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. any help is greatly appreciated.

The thing that bothers me the most from your current implementation of MVVM is the Command. Basically we only need to create one class that implements ICommand. Then we can create multiple properties from that class, each can execute different methods/codes. Example implementation of ICommand from another SO post :

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:

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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