加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在Caliburn Micro中使用Telerik RadWindow和自定义WindowM

发布时间:2020-12-15 21:05:16 所属栏目:百科 来源:网络整理
导读:我目前正在开发一个利用Caliburn Micro和Caliburn.Micro.Telerik的 WPF项目. 我的问题是双重的.首先,如果我创建View作为telerik:RadWindow,那么每当调用Show / ShowDialog方法时,窗口永远不会显示.如果我将视图创建为UserControl,那么它将显示. 其次TryClos
我目前正在开发一个利用Caliburn Micro和Caliburn.Micro.Telerik的 WPF项目.

我的问题是双重的.首先,如果我创建View作为telerik:RadWindow,那么每当调用Show / ShowDialog方法时,窗口永远不会显示.如果我将视图创建为UserControl,那么它将显示.

其次TryClose()在没有参数的情况下工作正常,但每当我尝试传入true / false时,窗口都不会关闭.

这里参考相关的代码片段:

Window Manager扩展:

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 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 defaultPromptResultValue,Action<string> onOK)
    {
        TelerikWindowManager.Prompt(title,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,settings);
    }

    public override void ShowWindow(object rootModel,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,settings);
                navWindow.Navigate(window);
            }
            else
            {
                CreateRadWindow(rootModel,false,settings).Show();
            }
            return;
        }
        base.ShowWindow(rootModel,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,object> settings)
    {
        var view = EnsureRadWindow(rootModel,ViewLocator.LocateForModel(rootModel,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,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,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;
    }
}

新用户视图模型:

[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,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

}

最后,从我们的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,82);


        _container.Compose(batch);
    }

如果有人对可能出现的事情有任何想法,我将非常感激.

提前致谢

解决方法

可以找到问题第一部分的答案 here.关键是将默认的RadWindow样式应用到主/ shell窗口.另一个提示:将以下内容添加到ShellView窗口,以便您的应用程序显示在任务栏中.

xmlns:navigation="clr-namespace:Telerik.Windows.Controls.Navigation;assembly=Telerik.Windows.Controls.Navigation"
    navigation:RadWindowInteropHelper.ShowInTaskbar="True"

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读