Tuesday, February 6, 2018

Issues using Telerik RadWindow and custom WindowManager in Caliburn Micro

Leave a Comment

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 Answers

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment