我通过练习一个简单的加法程序开始使用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
}
如果您需要更多信息,请告诉我。
答案 0 :(得分:1)
int
变量的默认值为0
。我认为,这对您有帮助
private int? _number1;
public int? firstargument
{
get { return _number1; }
set
{
this._number1 = value;
this.OnPropertyChanged("firstargument");
}
}
答案 1 :(得分:0)
在运行窗口中获得0
的原因是绑定属性都是int
,而0
是int
的默认值。
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;
}
}
}
注意:
int
的文本,所以在键入错误编号时可以使用int?
存储空值。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;
}
,a
,b
值。
答案 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);
}
}