C#主详细视图-恢复未保存的更改
我正在用Caliburn.Micro在C#中创建CRUD应用程序,我有一些主细节视图,如下所示: 我想要实现的是,当我做一些更改(例如,我将容量从47更改为50),然后选择另一个位置,比如位置4,再选择位置5,我的容量将是47,而不是现在的50 我在考虑一次性绑定,然后手动启动对viewmodel的绑定,但是viewmodel不应该知道视图,所以这似乎是个坏主意。下面是我的代码 XAML:C#主详细视图-恢复未保存的更改,c#,wpf,mvvm,caliburn.micro,C#,Wpf,Mvvm,Caliburn.micro,我正在用Caliburn.Micro在C#中创建CRUD应用程序,我有一些主细节视图,如下所示: 我想要实现的是,当我做一些更改(例如,我将容量从47更改为50),然后选择另一个位置,比如位置4,再选择位置5,我的容量将是47,而不是现在的50 我在考虑一次性绑定,然后手动启动对viewmodel的绑定,但是viewmodel不应该知道视图,所以这似乎是个坏主意。下面是我的代码 XAML: 视图模型: class PlacesTabViewModel : TabViewModel
视图模型:
class PlacesTabViewModel : TabViewModel
{
#region Fields
private BindableCollection<Place> _places;
private Place _selectedPlace;
#endregion
#region Methods
public PlacesTabViewModel()
{
using (var ctx = new DbCtx(App.DatabasePath))
{
_places = new BindableCollection<Place>(ctx.Places.OrderBy(p => p.Name));
}
}
public override string ToString()
{
return "Places";
}
#endregion
#region Events
public bool CanDeletePlace => _selectedPlace != null;
public bool CanSavePlace => (_selectedPlace != null) && _selectedPlace.IsValid();
public void DeletePlace()
{
using (var ctx = new DbCtx(App.DatabasePath))
{
try
{
ctx.Entry(SelectedPlace).State = EntityState.Deleted;
ctx.SaveChanges();
}
catch (DbUpdateException)
{
//TODO: Error
return;
}
Places.Remove(SelectedPlace);
NotifyOfPropertyChange(nameof(Places));
NotifyOfPropertyChange(() => CanDeletePlace);
NotifyOfPropertyChange(() => CanSavePlace);
}
}
public void SavePlace()
{
using (var ctx = new DbCtx(App.DatabasePath))
{
try
{
ctx.Places.Attach(_selectedPlace);
ctx.Entry(_selectedPlace).State = EntityState.Modified;
ctx.SaveChanges();
}
catch
{
//TODO: Error
}
NotifyOfPropertyChange(nameof(Places));
}
}
#endregion
#region Properties
public BindableCollection<Place> Places
{
get { return _places; }
set
{
if (value != _places)
{
_places = value;
NotifyOfPropertyChange(nameof(Places));
}
}
}
public Place SelectedPlace
{
get { return _selectedPlace; }
set
{
if (value != _selectedPlace)
{
_selectedPlace = value;
if (_selectedPlace != null)
{
_selectedPlace.PropertyChanged += (sender, args) =>
{
NotifyOfPropertyChange(() => CanSavePlace);
};
}
NotifyOfPropertyChange(nameof(SelectedPlace));
NotifyOfPropertyChange(() => CanDeletePlace);
NotifyOfPropertyChange(() => CanSavePlace);
}
}
}
#endregion
}
类PlacesTabViewModel:TabViewModel
{
#区域字段
私人收藏处;
私人场所_选择的场所;
#端区
#区域方法
公共场所StabViewModel()
{
使用(var ctx=newdbctx(App.DatabasePath))
{
_places=newbindablecolection(ctx.places.OrderBy(p=>p.Name));
}
}
公共重写字符串ToString()
{
返回“位置”;
}
#端区
#地区活动
public bool candeletplace=>\u selectedPlace!=null;
public bool CanSavePlace=>(_selectedPlace!=null)&&&_selectedPlace.IsValid();
公众地方()
{
使用(var ctx=newdbctx(App.DatabasePath))
{
尝试
{
ctx.Entry(SelectedPlace).State=EntityState.Deleted;
ctx.SaveChanges();
}
捕获(DbUpdateException)
{
//TODO:错误
返回;
}
位置。删除(选定位置);
财产变更通知(地点名称);
财产变更通知(()=>Candeletplace);
NotifyOfPropertyChange(()=>CanSavePlace);
}
}
公共无效存储位置()
{
使用(var ctx=newdbctx(App.DatabasePath))
{
尝试
{
ctx.Places.Attach(_selectedPlace);
ctx.Entry(_selectedPlace).State=EntityState.Modified;
ctx.SaveChanges();
}
抓住
{
//TODO:错误
}
财产变更通知(地点名称);
}
}
#端区
#区域属性
公众收集地点
{
获取{return\u places;}
设置
{
如果(值!=\u个位置)
{
_地点=价值;
财产变更通知(地点名称);
}
}
}
公共场所选定地点
{
获取{return\u selectedPlace;}
设置
{
如果(值!=\u选择的位置)
{
_selectedPlace=值;
如果(_selectedPlace!=null)
{
_selectedPlace.PropertyChanged+=(发件人,参数)=>
{
NotifyOfPropertyChange(()=>CanSavePlace);
};
}
财产变更通知(所选地点的名称);
财产变更通知(()=>Candeletplace);
NotifyOfPropertyChange(()=>CanSavePlace);
}
}
}
#端区
}
主窗口的ViewModel
class MainWindowViewModel : PropertyChangedBase
{
#region Fields
private BindableCollection<TabViewModel> _tabs = new BindableCollection<TabViewModel>();
#endregion
public MainWindowViewModel()
{
_tabs.Add(new PlacesTabViewModel());
}
#region Properties
public BindableCollection<TabViewModel> Tabs
{
get { return _tabs; }
set
{
if (value != _tabs)
{
_tabs = value;
NotifyOfPropertyChange(nameof(Tabs));
}
}
}
#endregion
}
class MainWindowViewModel:PropertyChangedBase
{
#区域字段
private BindableCollection_tabs=新建BindableCollection();
#端区
公共主窗口视图模型()
{
_tabs.Add(新的PlacesTabViewModel());
}
#区域属性
公共BindableCollection选项卡
{
获取{return\u tabs;}
设置
{
如果(值!=\u选项卡)
{
_tabs=值;
属性更改通知(选项卡名称);
}
}
}
#端区
}
WPF不知道正常属性。您必须使其成为依赖项属性,或者在您的情况下,您的VM必须实现INotifyPropertyChanged。当值更改时,它将自动更新
可能是您没有为所选地点的容量应用INotifyPropertyChanged属性
我认为这就是问题所在。没有魔法,你必须写出来。绑定到SelectedItem,并观察更改。当您选择一个地点时,您将收到更改通知。克隆对象。将其放入绑定到编辑器的CurrentEdit属性中。如果切换SelectedItem而不点击Save,则未保存的克隆将消失。当您点击Save时,获取克隆,在ItemsSource集合中查找原始,然后切换它们。或者,从克隆复制属性值,或者。
class MainWindowViewModel : PropertyChangedBase
{
#region Fields
private BindableCollection<TabViewModel> _tabs = new BindableCollection<TabViewModel>();
#endregion
public MainWindowViewModel()
{
_tabs.Add(new PlacesTabViewModel());
}
#region Properties
public BindableCollection<TabViewModel> Tabs
{
get { return _tabs; }
set
{
if (value != _tabs)
{
_tabs = value;
NotifyOfPropertyChange(nameof(Tabs));
}
}
}
#endregion
}