текстовое поле автоматически назначая значение по умолчанию wpf - PullRequest
0 голосов
/ 20 декабря 2018

Я начинаю изучать wpf с помощью mvvm, практикуя простую программу сложения.Мое приложение работает нормально.

Но при запуске приложения текстовое поле автоматически присваивает значение по умолчанию 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 голосов
/ 20 декабря 2018

Причина

Причина, по которой вы получаете 0 в своем рабочем окне, заключается в том, что все свойства привязки имеют int, а 0 является значением по умолчанию int.

0 из int является допустимым значением для системы привязки XAML, поэтому вы увидите, что все TextBox es содержат 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, если вы не конвертируете его самостоятельно или не напишитеновый IValueConverter.

Обновление

Чтобы реализовать команду Add, просто используйте поля вместо свойств.

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

Если вы хотите сохранить результат в модели, сохраните a, b, c значений.

0 голосов
/ 20 декабря 2018

Я обертываю свойство int модели в строковое свойство, потому что TextBox.Text является строкой, и все остальное приведет к ошибкам преобразования.

ViewModel нужна собственная строка, а не всегда преобразовывать вводимые пользователем данные в целое число, потому что пользователь может очистить поле или набрать '-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 голосов
/ 20 декабря 2018

Значением по умолчанию int переменных является 0.Я думаю, это поможет вам

 private int? _number1;
    public int? firstargument
    {
        get { return _number1; }
        set
        {
            this._number1 = value;
            this.OnPropertyChanged("firstargument");
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...