I am currently working on a WPF project that utilizes Caliburn Micro and Caliburn.Micro.Telerik.
My issues are twofold. Firstly, if I create the View as a telerik:RadWindow then whenever the Show / ShowDialog method is called the window never gets displayed. If I create the view as UserControl then it will display.
Secondly TryClose() works fine without parameters but whenever I try and pass in true / false the window does not close.
For reference here are the pertinent pieces of code:
Window Manager Extensions:
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); } }
Window Manager:
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 Window Conductor:
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; } }
New User View Model:
[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 }
Finally, from our 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); }
If anyone has any ideas on what may be up I would be super grateful.
Thanks in advance
0 comments:
Post a Comment