文本框自动分配默认值wpf

时间:2018-12-20 04:28:36

标签: c# wpf

我通过练习一个简单的加法程序开始使用mvvm学习wpf。我的应用程序运行正常。

但是在运行应用程序时,文本框会自动分配默认值0。

在用户提供任何输入之前,我不希望0。

view.xaml:

 <TextBox Height="28" Margin="112,56,46,0"  Text ="{Binding firstargument}"   Name="textBox1" VerticalAlignment="Top" />

ViewModel.cs

  private string _number1;
        public string firstargument
        {
            get { return _number1; }
            set
            {
                this._number1 = value;
                this.OnPropertyChanged("firstargument");

            }
        }

我的问题是执行后要在文本框中删除值0?

已编辑

ModelView.cs

 class ViewModel : INotifyPropertyChanged
    {


        public RelayCommand AddNew { get; set; }

        private int _number1;
        public int firstargument
        {
            get { return _number1; }
            set
            {


                this._number1 = value;
                this.OnPropertyChanged("firstargument");

            }
        }

        private int _number2;

        public int secondargument
        {
            get { return _number2; }
            set
            {
                this._number2 = value;

                this.OnPropertyChanged("secondargument");
            }
        }

        private int _number3;

        public int _addedargument
        {
            get { return _number3; }
            set
            {
                _number3 = value;
                this.OnPropertyChanged("_addedargument");
            }
        }
    public  ViewModel()
    {

        AddNew = new RelayCommand(o => AddNumbers());
    }


    private void AddNumbers()
    {
//Model instance is created here.
        Number p = new Number() { number1 = this._number1, number2 = this._number2 };

        var c = p.number1 + p.number2;
        _addedargument = c;

    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion

    }

view.Xaml

<Window x:Class="addition.Window1"
         xmlns:vm="clr-namespace:addition.ViewModel" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.DataContext>
        <vm:ViewModel />
    </Window.DataContext>
    <Grid>

        <Label Height="28" Margin="28,54,0,0" Name="Number1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="48">Number</Label>
        <TextBox Height="28" Margin="112,56,46,0"  Text ="{Binding Path = firstargument}"   Name="textBox1" VerticalAlignment="Top" />
        <Label Margin="28,106,0,128" Name="Number2" Width="58" HorizontalAlignment="Left">Number1</Label>
        <TextBox Height="28" Margin="112,120,46,120" Text ="{Binding  Path = secondargument }" Name="textBox2" />
        <Label Height="28" Margin="28,0,0,75" Name="label1" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="58">Number2</Label>
        <TextBox Height="23" Margin="112,0,46,68" Name="textBox3" Text="{Binding _addedargument}" VerticalAlignment="Bottom" />
        <Button Height="23"  HorizontalAlignment="Left" Margin="39,0,0,16" Name="button1" VerticalAlignment="Bottom" Width="75" Command="{Binding AddNew}">Button</Button>
    </Grid>
</Window>

编辑:实施walteerlv解决方案后,以下附加逻辑不起作用:

class ViewModel : INotifyPropertyChanged
    {
        int num;


        public RelayCommand AddNew { get; set; }

       private int? _number1;

public string FirstArgument
{

    get { return  _number1.ToString();}
    set
    {
        if (int.TryParse(_number1.ToString(), out num ))
        {
            this._number1 = num;
            OnPropertyChanged("FirstArgument");
        }
        else
        {
            _number1 = null;
        }
    }
}
        private int? _number2;

        public string secondargument
        {
            get { return _number2.ToString(); }

            set
            {
                if (int.TryParse(_number1.ToString(), out num))
                {
                    this._number2 = num;

                    this.OnPropertyChanged("secondargument");
                }
                else
                {
                    _number2 = null;
                }
            }
        }

        private int? _number3;

        public string _addedargument
        {
            get { return _number3.ToString(); }
            set
            {
                if (int.TryParse(_number1.ToString(), out num))
                {
                    this._number3 = num;

                    this.OnPropertyChanged("secondargument");
                }
                else
                {
                    _number3 = null;
                }
            }
        }



        public  ViewModel()
    {
        // The command receives an action on the constructor,
        // which is the action to execute when the command is invoked.


        AddNew = new RelayCommand(o => AddNumbers());



    }


    private void AddNumbers()
    {

        Number p = new Number() { number1 =this._number1.ToString(), number2 = this._number2.ToString() };

        MessageBox.Show(this._number1.ToString());
        int? c = Int32.Parse(p.number1) + Int32.Parse(p.number2);
        _addedargument = c.ToString();


    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion

    }

如果您需要更多信息,请告诉我。

3 个答案:

答案 0 :(得分:1)

int变量的默认值为0。我认为,这对您有帮助

 private int? _number1;
    public int? firstargument
    {
        get { return _number1; }
        set
        {
            this._number1 = value;
            this.OnPropertyChanged("firstargument");
        }
    }

答案 1 :(得分:0)

原因

在运行窗口中获得0的原因是绑定属性都是int,而0int的默认值。

0中的

int是XAML绑定系统的有效值,因此在键入任何内容之前,您会看到所有TextBox个元素都包含0


解决方案

您所有的属性都应为string并转换您的实际数字:

private int? _number1;

public string FirstArgument
{
    get => _number1?.ToString();
    set
    {
        if (int.TryParse(value, out var number))
        {
            _number1 = number;
            OnPropertyChanged("FirstArgument");
        }
        else
        {
            _number1 = null;
        }
    }
}

注意:

  1. 因为您可能会得到无法转换为int的文本,所以在键入错误编号时可以使用int?存储空值。
  2. 将数字转换为字符串,或将其转换为字符串,以便可以将其正确显示在XAML绑定系统中。
  3. 该属性应为字符串,不能为int?,因为XAML绑定系统不会自动将string转换为int,除非您自己转换或编写新的{ {1}}。

更新

要实现IValueConverter命令,只需使用字段而不是属性即可。

Add

如果要将结果存储到模型中,请存储private void AddNumbers() { var a = _number1?.Value ?? 0; var b = _number2?.Value ?? 0; var c = a + b; _addedargument = c; } ab值。

答案 2 :(得分:0)

我将模型的int属性包装在string属性中,因为TextBox.Text是一个字符串,其他任何东西都会产生转换错误。

ViewModel需要它自己的字符串,而不是总是将用户的输入转换为int,因为用户可能会清除该框,或者在键入“ -1”时途中途遇到的值不是有效数字。遇到转换错误时,WPF绑定无法更新视图模型,因此您不知道有问题。

    private string firstArgument;

    public string FirstArgument
    {
        get
        {
            return this.firstArgument;
        }

        set
        {
            this.firstArgument= value;

            int tempInt;
            if (int.TryParse(value, out tempInt))
            {
                this.Model.FirstArgument = tempInt;
            }

            this.NotifyPropertyChanged();
        }
    }

以下是我用来验证字符串是有效int的大多数代码。

    protected void NotifyPropertyChanged([CallerMemberName]string propertyName = null)
    {
        this.CheckForPropertyErrors();

        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }


    public override void CheckForPropertyErrors()
    {
        this.ValidateInt(this.FirstArgument , nameof(this.FirstArgument ));
    }


    protected void ValidateInt32(string value, string fieldName, string displayName = null)
    {
        int temp;
        if (!int.TryParse(value, out temp))
        {
            this.AddError(new ValidationError(fieldName, Constraints.NotInt32, $"{displayName ?? fieldName} must be an integer"));
        }
        else
        {
            this.RemoveError(fieldName, Constraints.NotInt32);
        }
    }