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# 当调用GoBack()时,NavigationService将导航到不存在的对象_C#_Wpf_Ninject_Composite Primary Key_Navigationservice - Fatal编程技术网

C# 当调用GoBack()时,NavigationService将导航到不存在的对象

C# 当调用GoBack()时,NavigationService将导航到不存在的对象,c#,wpf,ninject,composite-primary-key,navigationservice,C#,Wpf,Ninject,Composite Primary Key,Navigationservice,我正在开发一个WPF web应用程序,其主页使用ninject加载页面 基本上,我想知道是否有一种方法可以告诉NavigationService由于用户更新了复合键中的值而更改了Id 我会尽力多解释一点。我的MultiTagPage有一个MultiTagView模型,它显示一个由(MultiTagDef、Key、Value)组成的multitagvalue。还有一个DataGrid,其中包含具有相同键和MultiTagDef的其他值。如果您双击其中一个值,则会显示相应的multitagvalue

我正在开发一个WPF web应用程序,其主页使用ninject加载页面

基本上,我想知道是否有一种方法可以告诉NavigationService由于用户更新了复合键中的值而更改了Id

我会尽力多解释一点。我的MultiTagPage有一个MultiTagView模型,它显示一个由(MultiTagDef、Key、Value)组成的multitagvalue。还有一个DataGrid,其中包含具有相同键和MultiTagDef的其他值。如果您双击其中一个值,则会显示相应的multitagvalue

在数据库中,multitagvalue使用复合键(Multitagdef.Name、key、value)存储。因此,如果有人更新了一个multitagvalue,则Id会被更改(比如从(a,B,C)到(a,B,D))并保存,然后如果用户继续使用数据网格中的另一个multitagvalue(a,B,E)并可能删除该对象,则navigationservice会尝试加载(a,B,C)而不是(a,B,D)

该体系结构是为具有ID列的对象设计的,当然,ID列永远不会更改。不幸的是,在这种情况下,添加ID列不是一个选项。那么,有人对如何解决这个问题有什么建议吗?我应该在每次有人保存时尝试重新加载页面,还是可以告诉NavigationService当前对象的ID已更改

现在,代码:

从主页:

public partial class MainPage : IUIService
{
    public static readonly DependencyProperty MainModelProperty = PropertyHelper.Register<MainPage>(x => x.MainModel);

    public MainModel MainModel
    {
        get { return (MainModel)GetValue(MainModelProperty); }
        set { SetValue(MainModelProperty, value); }
    }

    private static readonly ILog log = LogManager.GetLogger(typeof(MainPage));

    public MainPage()
    {
        // Make doubly sure...
        ShowsNavigationUI = false;

        InitializeComponent();

        App.Kernel.Rebind<IUIService>().ToConstant(this);

        MainModel = App.Kernel.Get<MainModel>();
        WindowTitle = MainModel.Title;

        ContentFrame.Navigating += Navigating;
        ContentFrame.Navigated += Navigated;
        ContentFrame.NavigationFailed += NavigationFailed;
    }

    private void Navigating(object sender, NavigatingCancelEventArgs args)
    {
        object dataContext = null;
        if(ContentFrame.Content is FrameworkElement) {
            dataContext = ((FrameworkElement)ContentFrame.Content).DataContext;
        } else if(ContentFrame.Content is FrameworkContentElement) {
            dataContext = ((FrameworkContentElement)ContentFrame.Content).DataContext;
        }

        if(dataContext is ISaveable && ((ISaveable)dataContext).NeedsSave) {
            if(MessageControl.UnsavedSync() != MessageControl.Button.Yes) {
                args.Cancel = true;
            }
        }
    }

    private void Navigated(object sender, NavigationEventArgs e)
    {
        var mi = e.ExtraData as MenuItemModel;

        if(mi == null) {
            var page = e.Content as IMenuItemPage;

            if(page != null) {
                mi = page.MenuItem;
            }

            if(mi == null) {
                log.DebugFormat("Navigated to {0} ({1}) without menu item", e.Content, e.Uri);
                return;
            }
        }

        MainModel.CurrentMenuItem = mi;

        if(mi.Type != MenuItemType.Folder) {
            Settings.Default.AddRecentMenuItem(new RecentMenuItem(mi.MenuItem));
        }
    }

    #region Generic Edit command

    private void EditCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.Handled = true;
        e.CanExecute = false;

        var param = Unwrap(e.Parameter);
        var paramType = GetEditType(param);
        if(paramType == null || !editPages.ContainsKey(paramType)) {
            return;
        }

        e.CanExecute = ToConstructorArgument(param) != null;
    }

    private void EditExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        Edit(e.Parameter);
    }

    private void Edit(object param)
    {
        var paramType = GetEditType(param);
        if(paramType == null || !editPages.ContainsKey(paramType)) {
            log.WarnFormat("Page for param {0} (type {1}) not found", param, paramType);
            return;
        }

        if(param is IList) {
            var list = (IList)param;
            if(list.Count > 1000) {
                Show("Too many items selected", "Please select no more than 1000 items at a time", messageTheme: MessageTheme.Warning);
                return;
            }
        }

        var arg = ToConstructorArgument(param);
        if(arg == null) {
            log.Warn("Unexpected parameter " + param + " supplied to EditExecuted");
            return;
        }

        var pageType = editPages[paramType];

        try {
            log.DebugFormat("Got a parameter of type {0}, navigating to edit page {1}", param.GetType(), pageType);

            Navigate(MakePage(pageType, arg));
        } catch(Exception ex) {
            log.Error("Unable to load edit page for parameter " + param, ex);
        }
    }


    private static Page MakePage(Type pageType, params IParameter[] p)
    {
        var page = (Page)App.Kernel.Get(pageType, p);
        var dp = ClientUtil.GetViewModelProperty(page.GetType());
        if(dp != null) {
            page.Loaded += (o, args) => {
                var skrap = App.Kernel.Get(dp.PropertyType, p);
                page.SetValue(dp, App.Kernel.Get(dp.PropertyType, p));
            };
            page.Unloaded += (o, args) => {
                try {
                    page.ClearValue(dp);
                } catch(Exception e) {
                    // Often happens when datagrid is in edit mode when navigating away from page:
                    // http://connect.microsoft.com/VisualStudio/feedback/details/571967/wpf-datagrid-causes-crash-with-sorting-is-not-allowed-during-an-addnew-or-edititem-transaction
                    log.Warn("Error while unloading page", e);
                }
            };

            ViewModelBehavior.SetUpdateUIError(page, true);
        }

        return page;
    }

    #endregion

    #region Navigate command

    private void NavigateCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = e.Parameter is Type;
        e.Handled = true;
    }

    private void NavigateExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        var type = e.Parameter as Type;
        if(type == null) {
            return;
        }

        Navigate(MakePage(type));
        e.Handled = true;
    }

    #endregion

    #region IUIService implementation 

    public void Navigate(Type type, params Tuple<string, object>[] parameters)
    {
        Navigate(MakePage(type, parameters.Select(x => new ConstructorArgument(x.Item1, x.Item2)).ToArray()));
    }

    public void Navigate(Type type, MenuItemModel menuItem, params Tuple<string, object>[] parameters)
    {
        Navigate(MakePage(type, parameters.Select(x => new ConstructorArgument(x.Item1, x.Item2))
            .Prepend(new ConstructorArgument("menuItem", menuItem))
            .Prepend(new ConstructorArgument("props", menuItem.Params))
            .ToArray()), 
            menuItem);
    }

    public void Navigate(Page content, object extraData = null)
    {
        if(ContentFrame != null) {
            if(ContentFrame.Content is DependencyObject) {
                foreach(var dg in WpfUtil.FindDescendants<DataGrid>((DependencyObject)ContentFrame.Content)) {
                    while(!dg.CommitEdit()) { /* Keep committing */ }
                }
            }

            ContentFrame.Navigate(content, extraData);
        }
    }

    public bool NavigateBack()
    {
        if(ContentFrame != null && ContentFrame.CanGoBack) {
            ContentFrame.GoBack();
            return true;
        } 

        if(NavigationService != null && NavigationService.CanGoBack) {
            NavigationService.GoBack();
            return true;
        }

        return false;
    }

}
public分部类主页面:IUIService
{
公共静态只读DependencyProperty MainModelProperty=PropertyHelper.Register(x=>x.MainModel);
公共main模型main模型
{
获取{return(MainModel)GetValue(MainModelProperty);}
set{SetValue(MainModelProperty,value);}
}
private static readonly ILog log=LogManager.GetLogger(typeof(MainPage));
公共主页()
{
//加倍确保。。。
ShowsNavigationUI=false;
初始化组件();
App.Kernel.Rebind().ToConstant(this);
MainModel=App.Kernel.Get();
WindowTitle=MainModel.Title;
ContentFrame.Navigating+=导航;
ContentFrame.Navigated+=已导航;
ContentFrame.NavigationFailed+=NavigationFailed;
}
私有无效导航(对象发送方、导航取消事件args args)
{
对象dataContext=null;
if(ContentFrame.Content是FrameworkElement){
dataContext=((FrameworkElement)ContentFrame.Content).dataContext;
}else if(ContentFrame.Content是FrameworkContentElement){
dataContext=((FrameworkContentElement)ContentFrame.Content);
}
if(dataContext是ISaveable&((ISaveable)dataContext).NeedsSave){
if(MessageControl.UnsavedSync()!=MessageControl.Button.Yes){
args.Cancel=true;
}
}
}
已导航的专用void(对象发送方,NavigationEventArgs e)
{
var mi=e.ExtraData作为MenuItemModel;
if(mi==null){
var page=e.内容为IMenuItemPage;
如果(第页!=null){
mi=page.MenuItem;
}
if(mi==null){
DebugFormat(“导航到{0}({1}),没有菜单项”,e.Content,e.Uri);
返回;
}
}
MainModel.CurrentMenuItem=mi;
if(mi.Type!=MenuItemType.Folder){
Settings.Default.AddRecentMenuItem(新的RecentMenuItem(mi.MenuItem));
}
}
#区域通用编辑命令
私有void EditCanExecute(对象发送方,CanExecuteRouteEventArgs e)
{
e、 已处理=正确;
e、 CanExecute=false;
var param=展开(即参数);
var paramType=GetEditType(param);
if(paramType==null | |!editPages.ContainsKey(paramType)){
返回;
}
e、 CanExecute=ToConstructorArgument(param)!=null;
}
私有void EditExecuted(对象发送方,ExecutedRoutedEventArgs e)
{
编辑(如参数);
}
私有无效编辑(对象参数)
{
var paramType=GetEditType(param);
if(paramType==null | |!editPages.ContainsKey(paramType)){
log.WarnFormat(“找不到参数{0}(类型{1})的页面”,参数,参数类型);
返回;
}
如果(参数为IList){
变量列表=(IList)参数;
如果(list.Count>1000){
显示(“选择的项目太多”,“请一次选择的项目不超过1000个”,messageTheme:messageTheme.Warning);
返回;
}
}
var arg=ToConstructorArgument(param);
如果(arg==null){
log.Warn(“提供给EditExecuted的意外参数”+param+);
返回;
}
var pageType=editPages[paramType];
试一试{
DebugFormat(“获取类型为{0}的参数,导航到编辑页面{1}”,param.GetType(),pageType);
导航(MakePage(pageType,arg));
}捕获(例外情况除外){
日志错误(“无法加载参数“+param,ex”的编辑页);
}
}
私有静态页面MakePage(类型pageType,参数IPParameter[]p)
{
var page=(page)App.Kernel.Get(pageType,p);
var dp=ClientUtil.GetViewModelProperty(page.GetType());
如果(dp!=null){
页面加载+=(o,参数)=>{
var skrap=App.Kernel.Get(dp.PropertyType,p);
SetValue(dp,App.Kernel.Get(dp.PropertyType,p));
};
页面已卸载+=(o,参数)=>{
试一试{
第页:净价值(dp);
}捕获(例外e){
//在离开页面导航时,datagrid处于编辑模式时经常发生:
// http://connect.microsoft.com/VisualStudio/feedback/details/571967/wpf-datagrid-causes-crash-with-sorting-is-not-allowed-during-an-addnew-or-edititem-transaction