C# 文本框自动指定默认值wpf
通过练习一个简单的加法程序,我开始学习使用mvvm的wpf。我的应用程序运行良好 但在运行应用程序时,文本框会自动指定默认值0 我不希望在用户提供任何输入之前使用0 view.xaml: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 已编辑:
<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);
}
}