Wpf Caliburn.Micro silverlight多窗口管理器

Wpf Caliburn.Micro silverlight多窗口管理器,wpf,silverlight,silverlight-5.0,caliburn.micro,Wpf,Silverlight,Silverlight 5.0,Caliburn.micro,Silverlight中的现成Caliburn.Micro WindowManager实现似乎不支持多个窗口,因此我尝试创建一个自定义WindowManager来处理Silverlight 5中的多个窗口 我使用Caliburn.Micro中的WPF实现(它处理多个窗口)作为起点,所以我有下面的代码。这是一个好的起点吗 它的工作原理是在新窗口中打开所需的视图。不幸的是,当我在结果窗口中单击任何按钮时,我前面加了注释和“//>>>”的行似乎会导致异常-单击任何按钮似乎会尝试关闭窗口,然后抛出未处理

Silverlight中的现成Caliburn.Micro WindowManager实现似乎不支持多个窗口,因此我尝试创建一个自定义WindowManager来处理Silverlight 5中的多个窗口

我使用Caliburn.Micro中的WPF实现(它处理多个窗口)作为起点,所以我有下面的代码。这是一个好的起点吗

它的工作原理是在新窗口中打开所需的视图。不幸的是,当我在结果窗口中单击任何按钮时,我前面加了注释和“//>>>”的行似乎会导致异常-单击任何按钮似乎会尝试关闭窗口,然后抛出未处理的异常:

System.Exception: No target found for method MyMethod
如果我按如下方式更改ViewModelBinder.Bind方法,则结果窗口\view中的按钮将调用其viewmodel上的正确方法,但TryClose不再工作

   ViewModelBinder.Bind(rootModel, locatedView, context);
谁能告诉我这是什么原因吗?还是在Caliburn.Micro中为Silverlight 5实现多窗口管理器的替代方法

代码:

    /// <summary>
    /// Shows a window for the specified ViewModel.
    /// </summary>
    /// <param name="rootModel">The root ViewModel.</param>
    /// <param name="context">The context.</param>
    /// <param name="settings">The optional window settings.</param>
public virtual void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null)
        {
// Some custom code - I've confirmed it's not causing any issues

            CreateWindow(rootModel, false, context, settings).Show();
    }

    /// <summary>
    /// Creates a window.
    /// </summary>
    /// <param name="rootModel">The view model.</param>
    /// <param name="isDialog">Whethor or not the window is being shown as a dialog.</param>
    /// <param name="context">The view context.</param>
    /// <param name="settings">The optional settings.</param>
    /// <returns>The window.</returns>
    protected virtual Window CreateWindow(object rootModel, bool isDialog, object context, IDictionary<string, object> settings)
    {
        var locatedView = ViewLocator.LocateForModel(rootModel, null, context);            
            var view = EnsureWindow(rootModel, locatedView, isDialog);
/// >>>>  The following binding seems to cause an exception. Binding to locatedView instead of view corrects this, but then TryClose doesn't work
            ViewModelBinder.Bind(rootModel, view, context);

        ApplySettings(view, settings);

        new WindowConductor(rootModel, view);

        return view;
    }

    /// <summary>
    /// Makes sure the view is a window or is wrapped by one.
    /// </summary>
    /// <param name="model">The view model.</param>
    /// <param name="view">The view.</param>
    /// <param name="isDialog">Whethor or not the window is being shown as a dialog.</param>
    /// <returns>The window.</returns>
    protected virtual Window EnsureWindow(object model, object view, bool isDialog)
    {
        var window = view as Window;

        if (window == null)
        {
            window = new Window
            {
                Content = (FrameworkElement) view
            };

            window.SetValue(View.IsGeneratedProperty, true);
        }

        return window;
    }

    static void ApplySettings(object target, IEnumerable<KeyValuePair<string, object>> settings)
    {
        if (settings == null) 
            return;

        var type = target.GetType();

        foreach (var pair in settings)
        {
            var propertyInfo = type.GetProperty(pair.Key);

            if (propertyInfo != null)
                propertyInfo.SetValue(target, pair.Value, null);
        }
    }
其他详细信息:

    /// <summary>
    /// Shows a window for the specified ViewModel.
    /// </summary>
    /// <param name="rootModel">The root ViewModel.</param>
    /// <param name="context">The context.</param>
    /// <param name="settings">The optional window settings.</param>
public virtual void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null)
        {
// Some custom code - I've confirmed it's not causing any issues

            CreateWindow(rootModel, false, context, settings).Show();
    }

    /// <summary>
    /// Creates a window.
    /// </summary>
    /// <param name="rootModel">The view model.</param>
    /// <param name="isDialog">Whethor or not the window is being shown as a dialog.</param>
    /// <param name="context">The view context.</param>
    /// <param name="settings">The optional settings.</param>
    /// <returns>The window.</returns>
    protected virtual Window CreateWindow(object rootModel, bool isDialog, object context, IDictionary<string, object> settings)
    {
        var locatedView = ViewLocator.LocateForModel(rootModel, null, context);            
            var view = EnsureWindow(rootModel, locatedView, isDialog);
/// >>>>  The following binding seems to cause an exception. Binding to locatedView instead of view corrects this, but then TryClose doesn't work
            ViewModelBinder.Bind(rootModel, view, context);

        ApplySettings(view, settings);

        new WindowConductor(rootModel, view);

        return view;
    }

    /// <summary>
    /// Makes sure the view is a window or is wrapped by one.
    /// </summary>
    /// <param name="model">The view model.</param>
    /// <param name="view">The view.</param>
    /// <param name="isDialog">Whethor or not the window is being shown as a dialog.</param>
    /// <returns>The window.</returns>
    protected virtual Window EnsureWindow(object model, object view, bool isDialog)
    {
        var window = view as Window;

        if (window == null)
        {
            window = new Window
            {
                Content = (FrameworkElement) view
            };

            window.SetValue(View.IsGeneratedProperty, true);
        }

        return window;
    }

    static void ApplySettings(object target, IEnumerable<KeyValuePair<string, object>> settings)
    {
        if (settings == null) 
            return;

        var type = target.GetType();

        foreach (var pair in settings)
        {
            var propertyInfo = type.GetProperty(pair.Key);

            if (propertyInfo != null)
                propertyInfo.SetValue(target, pair.Value, null);
        }
    }
它看起来像Caliburn.Micro的WPF版本,它成功地将viewmodel绑定到一个窗口对象,但是在Silverlight中尝试同样的事情会导致问题

当我深入研究Caliburn.Micro代码时,它看起来像默认ActionMessage.SetMethodBinding中的以下调用:

currentElement = VisualTreeHelper.GetParent(currentElement);
在Silverlight中没有将窗口作为我的视图的父级,但在WPF中是这样的,并且由于ViewModel绑定到窗口,因此它从未找到ViewModel,因此不调用操作


后来我发现,将CreateWindow更改为绑定到locatedView(这是UserControl)而不是view(这是一个包装UserControl的窗口)实际上在我的主项目中可以正常工作,但在我测试它的小样本项目中却不行。我仍然不明白为什么会这样,但我还没有太多时间去深入研究

有什么例外?没有找到目标?如果听起来CM操作没有指向viewmodel,那么它们应该是beYes,这就是错误。请参阅相关的其他详细信息。