- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在开发一个使用 Caliburn Micro 和 Caliburn.Micro.Telerik 的 WPF 项目。
我的问题是双重的。首先,如果我将 View 创建为 telerik:RadWindow,那么无论何时调用 Show/ShowDialog 方法,窗口都不会显示。如果我将 View 创建为 UserControl,那么它将显示。
其次,TryClose() 在没有参数的情况下工作正常,但每当我尝试传入 true/false 时,窗口都不会关闭。
这里有相关的代码供引用:
窗口管理器扩展:
public static class IWindowManagerExtensions
{
/// <summary>
/// Opens an Alert modal window
/// </summary>
public static void Alert(this IWindowManager windowManager, string title, string message)
{
TelerikWindowManager.Alert(title, message);
}
/// <summary>
/// Opens an Alert modal window
/// </summary>
public static void Alert(this IWindowManager windowManager, DialogParameters dialogParameters)
{
TelerikWindowManager.Alert(dialogParameters);
}
/// <summary>
/// Opens a Confirm modal window
/// </summary>
public static void Confirm(this IWindowManager windowManager, string title, string message, System.Action onOK, System.Action onCancel = null)
{
TelerikWindowManager.Confirm(title, message, onOK, onCancel);
}
/// <summary>
/// Opens a Confirm modal window
/// </summary>
public static void Confirm(this IWindowManager windowManager, DialogParameters dialogParameters)
{
TelerikWindowManager.Confirm(dialogParameters);
}
/// <summary>
/// Opens a Prompt modal window
/// </summary>
public static void Prompt(this IWindowManager windowManager, string title, string message, string defaultPromptResultValue, Action<string> onOK)
{
TelerikWindowManager.Prompt(title, message, defaultPromptResultValue, onOK);
}
/// <summary>
/// Opens a Prompt modal window
/// </summary>
public static void Prompt(this IWindowManager windowManager, DialogParameters dialogParameters)
{
TelerikWindowManager.Prompt(dialogParameters);
}
}
窗口管理器:
public class TelerikWindowManager : WindowManager
{
public override bool? ShowDialog(object rootModel, object context = null, IDictionary<string, object> settings = null)
{
var viewType = ViewLocator.LocateTypeForModelType(rootModel.GetType(), null, null);
if (typeof(RadWindow).IsAssignableFrom(viewType)
|| typeof(UserControl).IsAssignableFrom(viewType))
{
var radWindow = CreateRadWindow(rootModel, true, context, settings);
radWindow.ShowDialog();
return radWindow.DialogResult;
}
return base.ShowDialog(rootModel, context, settings);
}
public override void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null)
{
var viewType = ViewLocator.LocateTypeForModelType(rootModel.GetType(), null, null);
if (typeof(RadWindow).IsAssignableFrom(viewType)
|| typeof(UserControl).IsAssignableFrom(viewType))
{
NavigationWindow navWindow = null;
if (Application.Current != null && Application.Current.MainWindow != null)
{
navWindow = Application.Current.MainWindow as NavigationWindow;
}
if (navWindow != null)
{
var window = CreatePage(rootModel, context, settings);
navWindow.Navigate(window);
}
else
{
CreateRadWindow(rootModel, false, context, settings).Show();
}
return;
}
base.ShowWindow(rootModel, context, settings);
}
/// <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 popup settings.</param>
/// <returns>The window.</returns>
protected virtual RadWindow CreateRadWindow(object rootModel, bool isDialog, object context, IDictionary<string, object> settings)
{
var view = EnsureRadWindow(rootModel, ViewLocator.LocateForModel(rootModel, null, context), isDialog);
ViewModelBinder.Bind(rootModel, view, context);
var haveDisplayName = rootModel as IHaveDisplayName;
if (haveDisplayName != null && !ConventionManager.HasBinding(view, RadWindow.HeaderProperty))
{
var binding = new Binding("DisplayName") { Mode = BindingMode.TwoWay };
view.SetBinding(RadWindow.HeaderProperty, binding);
}
ApplyRadWindowSettings(view, settings);
new RadWindowConductor(rootModel, view);
return view;
}
bool ApplyRadWindowSettings(object target, IEnumerable<KeyValuePair<string, object>> settings)
{
if (settings != null)
{
var type = target.GetType();
foreach (var pair in settings)
{
var propertyInfo = type.GetProperty(pair.Key);
if (propertyInfo != null)
{
propertyInfo.SetValue(target, pair.Value, null);
}
}
return true;
}
return false;
}
/// <summary>
/// Makes sure the view is a window is 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 RadWindow EnsureRadWindow(object model, object view, bool isDialog)
{
var window = view as RadWindow;
if (window == null)
{
var contentElement = view as FrameworkElement;
if (contentElement == null)
throw new ArgumentNullException("view");
window = new RadWindow
{
Content = view,
SizeToContent = true,
};
AdjustWindowAndContentSize(window, contentElement);
window.SetValue(View.IsGeneratedProperty, true);
var owner = GetActiveWindow();
if (owner != null)
{
window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
window.Owner = owner;
}
else
{
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
}
}
else
{
var owner = GetActiveWindow();
if (owner != null && isDialog)
{
window.Owner = owner;
}
}
return window;
}
/// <summary>
/// Initializes Window size with values extracted by the view.
///
/// Note:
/// The real size of the content will be smaller than provided values.
/// The form has the header (title) and border so they will take place.
///
/// </summary>
/// <param name="window">The RadWindow</param>
/// <param name="view">The view</param>
private static void AdjustWindowAndContentSize(RadWindow window, FrameworkElement view)
{
window.MinWidth = view.MinWidth;
window.MaxWidth = view.MaxWidth;
window.Width = view.Width;
window.MinHeight = view.MinHeight;
window.MaxHeight = view.MaxHeight;
window.Height = view.Height;
// Resetting view's settings
view.Width = view.Height = Double.NaN;
view.MinWidth = view.MinHeight = 0;
view.MaxWidth = view.MaxHeight = int.MaxValue;
// Stretching content to the Window
view.VerticalAlignment = VerticalAlignment.Stretch;
view.HorizontalAlignment = HorizontalAlignment.Stretch;
}
/// <summary>
/// Infers the owner of the window.
/// </summary>
/// <returns>The owner.</returns>
protected virtual Window GetActiveWindow()
{
if (Application.Current == null)
{
return null;
}
var active = Application.Current
.Windows.OfType<Window>()
.FirstOrDefault(x => x.IsActive);
return active ?? Application.Current.MainWindow;
}
public static void Alert(string title, string message)
{
RadWindow.Alert(new DialogParameters { Header = title, Content = message });
}
public static void Alert(DialogParameters dialogParameters)
{
RadWindow.Alert(dialogParameters);
}
public static void Confirm(string title, string message, System.Action onOK, System.Action onCancel = null)
{
var dialogParameters = new DialogParameters
{
Header = title,
Content = message
};
dialogParameters.Closed += (sender, args) =>
{
var result = args.DialogResult;
if (result.HasValue && result.Value)
{
onOK();
return;
}
if (onCancel != null)
onCancel();
};
Confirm(dialogParameters);
}
public static void Confirm(DialogParameters dialogParameters)
{
RadWindow.Confirm(dialogParameters);
}
public static void Prompt(string title, string message, string defaultPromptResultValue, Action<string> onOK)
{
var dialogParameters = new DialogParameters
{
Header = title,
Content = message,
DefaultPromptResultValue = defaultPromptResultValue,
};
dialogParameters.Closed += (o, args) =>
{
if (args.DialogResult.HasValue && args.DialogResult.Value)
onOK(args.PromptResult);
};
Prompt(dialogParameters);
}
public static void Prompt(DialogParameters dialogParameters)
{
RadWindow.Prompt(dialogParameters);
}
}
Rad 窗口导体:
internal class RadWindowConductor
{
private bool deactivatingFromView;
private bool deactivateFromViewModel;
private bool actuallyClosing;
private readonly RadWindow view;
private readonly object model;
public RadWindowConductor(object model, RadWindow view)
{
this.model = model;
this.view = view;
var activatable = model as IActivate;
if (activatable != null)
{
activatable.Activate();
}
var deactivatable = model as IDeactivate;
if (deactivatable != null)
{
view.Closed += Closed;
deactivatable.Deactivated += Deactivated;
}
var guard = model as IGuardClose;
if (guard != null)
{
view.PreviewClosed += PreviewClosed;
}
}
private void Closed(object sender, EventArgs e)
{
view.Closed -= Closed;
view.PreviewClosed -= PreviewClosed;
if (deactivateFromViewModel)
{
return;
}
var deactivatable = (IDeactivate)model;
deactivatingFromView = true;
deactivatable.Deactivate(true);
deactivatingFromView = false;
}
private void Deactivated(object sender, DeactivationEventArgs e)
{
if (!e.WasClosed)
{
return;
}
((IDeactivate)model).Deactivated -= Deactivated;
if (deactivatingFromView)
{
return;
}
deactivateFromViewModel = true;
actuallyClosing = true;
view.Close();
actuallyClosing = false;
deactivateFromViewModel = false;
}
private void PreviewClosed(object sender, WindowPreviewClosedEventArgs e)
{
if (e.Cancel == true)
{
return;
}
var guard = (IGuardClose)model;
if (actuallyClosing)
{
actuallyClosing = false;
return;
}
bool runningAsync = false, shouldEnd = false;
guard.CanClose(canClose =>
{
Execute.OnUIThread(() =>
{
if (runningAsync && canClose)
{
actuallyClosing = true;
view.Close();
}
else
{
e.Cancel = !canClose;
}
shouldEnd = true;
});
});
if (shouldEnd)
{
return;
}
e.Cancel = true;
runningAsync = true;
}
}
新用户 View 模型:
[Export, PartCreationPolicy(CreationPolicy.NonShared)]
[ExportController("NewUserViewModel")]
public class NewUserViewModel : FeatureWindowBase
{
#region Fields
private User _creatingUser;
private User _userToAdd;
#endregion
#region Properties
public bool IsOpen;
public User UserToAdd
{
get
{
return _userToAdd;
}
set
{
_userToAdd = value;
NotifyOfPropertyChange(() => UserToAdd);
}
}
public IEnumerable<Entity> AddedUsers => new List<Entity>() { UserToAdd };
#endregion
#region Constructors
[ImportingConstructor]
public NewUserViewModel(IWindowManager windowManager,
IEventAggregator eventAggregator,
IEntityManagerProvider<BearPawEntities> entityManagerProvider,
IGlobalCache globalCache) :
base(windowManager, eventAggregator, entityManagerProvider, globalCache)
{
}
#endregion
protected override void OnViewLoaded(object view)
{
base.OnViewLoaded(view);
// un-comment the following if you want to use the Global Cache
SetupGlobalCache<User>(Manager);
_creatingUser = Manager.Users.FirstOrDefault(u => u.UserName ==
Manager.AuthenticationContext.Principal.Identity
.Name);
UserToAdd = new User()
{
CreatedBy = _creatingUser,
CreatedDate = DateTime.Now,
ModifiedBy = _creatingUser,
ModifiedDate = DateTime.Now
};
DisplayName = "Add New User";
IsOpen = true;
}
#region Methods
public async Task CreateUser()
{
try
{
var newAuth = new UserAuthentication()
{
Password = Security.CreateSaltedPasswordForNewUser("LetMeIn"),
Salt = Security.LastSalt,
CreatedBy = _creatingUser,
CreatedDate = DateTime.Now,
ModifiedBy = _creatingUser,
ModifiedDate = DateTime.Now
};
Security.ClearLastSalt();
Manager.AddEntity(newAuth);
UserToAdd.UserAuthentication = newAuth;
Manager.AddEntity(UserToAdd);
var saveResponse = await Manager.TrySaveChangesAsync();
if (saveResponse.Ok)
{
TryClose(true);
}
}
catch (Exception)
{
throw;
}
}
#endregion
}
最后,来 self 们的 App Bootstrapper:
protected override void Configure()
{
IdeaBlade.Core.Composition.CompositionHost.IgnorePatterns.Add("xunit.*");
IdeaBlade.Core.Composition.CompositionHost.IgnorePatterns.Add("BearPaw.Client.*");
IdeaBlade.Core.Composition.CompositionHost.IgnorePatterns.Add("BearPaw.Clients.*");
IdeaBlade.Core.Composition.CompositionHost.IgnorePatterns.Add("Caliburn.*");
IdeaBlade.Core.Composition.CompositionHost.IgnorePatterns.Add("JetBrains.*");
IdeaBlade.Core.Composition.CompositionHost.IgnorePatterns.Add("FluentAssertions.*");
var conventions = new RegistrationBuilder();
conventions.ForTypesDerivedFrom<IBearPawFeature>()
.Export()
.SetCreationPolicy(CreationPolicy.NonShared);
_container = new CompositionContainer(
new AggregateCatalog(
AssemblySource.Instance.Select(x=> new AssemblyCatalog(x, conventions)).OfType<ComposablePartCatalog>()
)
);
var batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new TelerikWindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue<IEntityManagerProvider<BearPawEntities>>(new MainEntityManagerProvider());
batch.AddExportedValue<IEntityManagerProvider<BearPawReportingEntities>>(new ReportingEntityManagerProvider());
batch.AddExportedValue(_container);
// This is essential to enable Telerik's conventions
TelerikConventions.Install();
AddKeyBindingTriggers();
VisualStudio2013Palette.LoadPreset(VisualStudio2013Palette.ColorVariation.Dark);
VisualStudio2013Palette.Palette.BasicColor = Color.FromArgb(255, 77, 77, 82);
_container.Compose(batch);
}
如果有人对可能发生的事情有任何想法,我将非常感激。
提前致谢
最佳答案
可以找到问题第一部分的答案 here.关键是将默认的 RadWindow 样式应用到您的主/外壳窗口。另一个提示:将以下内容添加到 ShellView 窗口,以便您的应用程序显示在任务栏中。
xmlns:navigation="clr-namespace:Telerik.Windows.Controls.Navigation;assembly=Telerik.Windows.Controls.Navigation"
navigation:RadWindowInteropHelper.ShowInTaskbar="True"
关于c# - 在 Caliburn Micro 中使用 Telerik RadWindow 和自定义 WindowManager 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42124065/
最近我看到this详细说明 Caliburn 有多棒的文档(实际上并没有将它与微框架进行比较,这就足够了)。我在 Caliburn 工作了一年多,对它了解不多。 所以也许有人可以解释以下内容(其中一些
我有以下 ViewModel,我正在使用 Caliburn Micro。 IWindowManager 实例已正确解析,并且所有代码都可以正常工作。如 TODO 注释所示,我需要获取对当前窗口的引用,
所以我在 Caliburn.Micro 上摆弄了一下,突然发现了一些有趣的东西。 我有一个名为 Maximum 的 ViewModel 属性,类型为 int,通过命名约定与 CM 自动绑定(bind)
如果我的 View 中有一个名为 Save 的按钮,那么我可以将 Save 属性添加到我的 ViewModel,Caliburn.Micro 会自动将它绑定(bind)到我的按钮的内容。例如: pub
我一直在研究开发一个新的 MVVM WPF 桌面应用程序,并已将 Caliburn 和 Caliburn.Micro 列入候选名单。 我特别喜欢您在 Caliburn 中获得的自动绑定(bind)属性
当我使用绑定(bind)约定时在caliburn中,并将内容控件命名为“CurrentPresenter” 框架自动绑定(bind)到虚拟机并定位相关 View 。 如果我手动执行此绑定(bind),
我将 ViewModels 绑定(bind)到 ContentControls 并让 Caliburn 负责创建和绑定(bind) View 。但是,我想根据我绑定(bind)的 ContentCon
我从 Caliburn.micro 开始,我有点困惑。假设我有一个带有 2 个 Pane 的 UI,例如(这是一个假示例)CustomersView 和 CustomerView,以及 2 个相应的
我一直在尝试将 Caliburn.Micro MVVM 框架集成到我处于中间位置的 C# WPF 项目中。 我目前只有三个 View 模型: ShellViewModel -(带有 ContentCo
Caliburn.Micro 是否有与 Catel's 类似的功能? [ExposeAttribute] ? 有没有其他方法可以减轻 Caliburn.Micro 中传递属性的工作? (即模型中的属性
我想弄清楚如何将文本添加到列表框的底部并显示它。在带有代码的 WPF 中,我会捕获 ScrollViewer 并对其进行操作,但我无法弄清楚如何使用 Caliburn 来做到这一点... 最佳答案 您
我这样做: 问题是,这同时是主窗口上定义的主导体,我用它控制通过其他窗口的导航,所以我不能从 MetroWindow 继承,至少尝试更改 ViewModel 中的标题: public class S
我试图弄清楚如何成功地让 Caliburn Micro 在 Windows Phone 8.1 应用程序中从一个页面导航到另一个页面。 我的第一页加载得很好,正如我的 App 类中所指定的: prot
我正在用不同的项目编写解决方案。我使用caliburn micro编写了2个wpf客户端。它们都具有一个 map 控件,该控件绘制了一些图层和一个listview。我想在不同项目中托管通用控件,以便两
在尝试学习 GameLibrary 示例应用程序的源代码时,我看到了这样一行: ConventionManager.AddElementConvention(Rating.ValueProperty,
我正在使用 C# 和 Caliburn。 是否有一种全局方式来捕获所有 View 模型中的所有异常? 如果从 DI/IoC 容器导入过程中出现某种异常怎么办? 我基本上想在发生这种情况时显示一个消息框
位于http://caliburnmicro.com的Caliburn.Micro主页提出以下声明,但我无法使用该示例中可以想到的任何变体使CM与PasswordBox控件一起使用。因为名称不同,所以
我正在迈出 MVVM 的第一步。 我正在使用 Caliburn.Micro 作为我的 MVVM 框架。 我有以下代码: using System; using System.Collections.G
我正在开发一个使用 Caliburn Micro 的 WPF 项目。我遇到了一个问题,即第二次打开 View 时, View 中的控件没有得到更新。第一次数据绑定(bind)工作正常。 当我第二次调用
在我的 WPF Caliburn.Micro 应用程序中,我有一个 TabControl。我希望能够根据需要关闭标签。我在这里找到了一种方法: http://devlicio.us/blogs/rob
我是一名优秀的程序员,十分优秀!