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