我在WPF应用程序中有一个ViewModel和一个View。在屏幕上有一系列输入(日期选择器,文本框和组合框)。
输入绑定到ViewModel的NewItem属性,DataGrid绑定到WorkLog集合属性。
当用户点击“添加”按钮时,我希望将NewItem添加到WorkLog集合中,并重置NewItem属性以允许用户添加更多项目。问题是,当我添加项目时,如果我重新实例化NewItem,那么控件仍然会被填充,但在后台,VM值都是默认值(或空值),因此它不起作用。
如何重置NewItem属性并更新UI以反映这一点?我尝试使用INotifyPropertyChanged无效(因为我设置的是新实例而不是更改值)。
我为了简洁而修剪了代码
模型
public class WorkLogItem : INotifyPropertyChanged
{
public WorkLogItem()
{
this.Datestamp = DateTime.Today;
this.Staff = new Lookup();
this.WorkItem = new Lookup();
}
#region ID
private Int32 _ID;
public Int32 ID
{
get { return this._ID; }
set
{
this._ID = value;
FirePropertyChanged("ID");
}
}
#endregion
#region Datestamp
private DateTime? _Datestamp;
public DateTime? Datestamp
{
get { return this._Datestamp; }
set
{
this._Datestamp = value;
FirePropertyChanged("Datestamp");
}
}
#endregion
#region Staff
private Model.Lookup _Staff;
public Model.Lookup Staff
{
get { return this._Staff; }
set
{
this._Staff = value;
FirePropertyChanged("Staff");
}
}
#endregion
#region WorkItem
private Model.Lookup _WorkItem;
public Model.Lookup WorkItem
{
get { return this._WorkItem; }
set
{
this._WorkItem = value;
FirePropertyChanged("WorkItem");
}
}
#endregion
#region Hours
private Decimal _Hours;
public Decimal Hours
{
get { return this._Hours; }
set
{
this._Hours = value;
FirePropertyChanged("Hours");
}
}
#endregion
public event PropertyChangedEventHandler PropertyChanged;
// Create the OnPropertyChanged method to raise the event
protected void FirePropertyChanged(String name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
}
}
查看模型
public Model.WorkLogItem NewItem { get; set; }
public ObservableCollection<Model.WorkLogItem> WorkLog { get; set; }
查看
<Label Content="Date " />
<DatePicker SelectedDate="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.NewItem.Datestamp, NotifyOnSourceUpdated=True}" />
<Label Content="Work Item " />
<ComboBox Grid.Column="1" Grid.Row="2" DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.WorkItems}" ItemsSource="{Binding}" DisplayMemberPath="Value" SelectedValuePath="ID" SelectedItem="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.WorkLogItem.Type, NotifyOnSourceUpdated=True}" IsSynchronizedWithCurrentItem="True" />
<Label Grid.Row="3" Content="Hours " />
<TextBox Grid.Column="1" Grid.Row="3" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.NewItem.Hours, NotifyOnSourceUpdated=True}" />
C#
在Window_Loaded中:
this.DataContext = this.VM;
在Add_Click
中this.VM.WorkLog.Add(this.VM.NewItem);
this.VM.NewItem = new Model.WorkLogItem();
答案 0 :(得分:3)
您的ViewModel
还必须实施INotifyPropertyChanged
public class ViewModel : INotifyPropertyChanged
{
private Model.WorkLogItem _newItem;
public ViewModel()
{
NewItem = new Model.WorkLogItem();
WorkLog = new ObservableCollection<Model.WorkLogItem>();
}
public Model.WorkLogItem NewItem
{
get { return _newItem; }
set
{
_newItem = value;
FirePropertyChanged("NewItem");
}
}
public ObservableCollection<Model.WorkLogItem> WorkLog { get; set; }
// INotifyPropertyChanged implementation here...
}
绑定到ComboBox
时,请务必使用Mode=TwoWay
:
<ComboBox ... SelectedItem="{Binding ... Mode=TwoWay}" />
答案 1 :(得分:0)
我这样做的方法是在我的数据对象中设置一个空构造函数,将其所有属性设置为默认值。然后当我想“重置”一个视图到所有空字段时,我只是将我的数据绑定属性设置为一个新项:
NewItem = new YourDataType();
这会像您期望的那样更新所有数据绑定控件属性。请注意,我的数据类型类都实现了INotifyPropertyChanged
接口,并且这种清除UI控件的方法只有在实现它时才有效。