Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#主详细视图-恢复未保存的更改_C#_Wpf_Mvvm_Caliburn.micro - Fatal编程技术网

C#主详细视图-恢复未保存的更改

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

我正在用Caliburn.Micro在C#中创建CRUD应用程序,我有一些主细节视图,如下所示:

我想要实现的是,当我做一些更改(例如,我将容量从47更改为50),然后选择另一个位置,比如位置4,再选择位置5,我的容量将是47,而不是现在的50

我在考虑一次性绑定,然后手动启动对viewmodel的绑定,但是viewmodel不应该知道视图,所以这似乎是个坏主意。下面是我的代码

XAML:


视图模型:

    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
}