C# 文本框自动指定默认值wpf

C# 文本框自动指定默认值wpf,c#,wpf,C#,Wpf,通过练习一个简单的加法程序,我开始学习使用mvvm的wpf。我的应用程序运行良好 但在运行应用程序时,文本框会自动指定默认值0 我不希望在用户提供任何输入之前使用0 view.xaml: <TextBox Height="28" Margin="112,56,46,0" Text ="{Binding firstargument}" Name="textBox1" VerticalAlignment="Top" /> 我的问题是在执行后删除textbox中的值0 已编辑:

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

但在运行应用程序时,文本框会自动指定默认值0

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

view.xaml:

 <TextBox Height="28" Margin="112,56,46,0"  Text ="{Binding firstargument}"   Name="textBox1" VerticalAlignment="Top" />
我的问题是在执行后删除textbox中的值0

已编辑

ModelView.cs

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

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

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

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

 private int? _number1;
    public int? firstargument
    {
        get { return _number1; }
        set
        {
            this._number1 = value;
            this.OnPropertyChanged("firstargument");
        }
    }
理由 在运行窗口中获得
0
的原因是绑定属性都是
int
,而
0
int
的默认值

int
0
是XAML绑定系统的有效值,因此在键入任何内容之前,您将看到所有的
文本框都包含
0


解决方案 您的所有属性都应为
字符串
,并将实际数字转换为:

private int? _number1;

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

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

  • 更新 要实现
    Add
    命令,只需使用字段而不是属性

    private void AddNumbers()
    {
        var a = _number1?.Value ?? 0;
        var b = _number2?.Value ?? 0;
        var c = a + b;
        _addedargument = c;
    }
    

    如果要将结果存储到模型中,请存储
    a
    b
    c
    值。

    我将模型的int属性包装在字符串属性中,因为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);
            }
        }
    

    我已经尝试了您提供的所有代码,得到了一个没有任何意外字符串(如
    0
    )的空文本块。所以您可能丢失了其他影响此行为的重要代码。@walterlv我已经提供了viewmodel和view的完整代码。让我知道你是否可以复制这个行为。这个问题有太多的修改,很难理解。这个问题需要提供一个单一的答案。我怀疑您只是需要在绑定上使用一个转换器,并将属性设置为可为null的int。其他提示:与其使用字符串来包含属性的名称,不如使用
    nameof(YourProperty)
    。您还可以进一步使用,这样大多数时候您甚至不需要这样做。@walteerlv感谢您的评论,我已经更改了代码,问题已经解决。但现在,更改代码后,我的添加逻辑不起作用。更改后,我已更新了有问题的新代码。您的add命令需要更改以使用
    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);
            }
        }