【问题标题】:How to show a "closed" Desktop window in Ext.Net?如何在 Ext.Net 中显示“关闭”的桌面窗口?
【发布时间】:2013-06-28 04:29:47
【问题描述】:

情况:

我正在使用桌面组件开发 Ext.Net Web 应用程序,但在第一次创建窗口后无法打开它。

循环从“索引”视图开始,它只是构建主桌面环境。在这个视图中,创建了一个具有 JS 处理函数的模块,如下所示:

.Modules(
     X.DesktopModule()
         .ModuleID("ModuleTitle")
         .Shortcut(
         X.DesktopShortcut()
             .Name("Module Title")
             .IconCls("custom-icon")
              .Handler("loadModuleWindow(Desktop,'AssetManager');")
  )

然后,处理函数“loadModuleWindow”有责任决定窗口是必须第一次创建还是已经创建,只需要再次显示:

function loadModuleWindow(callingContainer, moduleId) {

    //Dynamically build name of script by convention       
    loadScriptFile("Scripts/" + moduleId + "Scripts.js", "js");

    //Only create new window if it hasn't been created already
    if (App[moduleId] == undefined) {
        App.direct.CreateModuleWindow(callingContainer.id, moduleId);
    } else {
        App[moduleId].show();
    }
}

Desktop 创建并第一次调用Module 时,会调用代码隐藏方法“CreateModuleWindow”并将Window 返回给客户端。

窗口设置为:

window.CloseAction = CloseAction.Hide;

到目前为止一切正常,问题出现在窗口关闭时(通过单击它的 [X] 关闭按钮)。 正如预期的那样,窗口从当前视图中隐藏,任务栏上的“指示器”也被删除。

您可能已经猜到了,使用 Handler ("loadModuleWindow") 的目的是在 Window 已经加载过一次的情况下避免服务器调用。

但是,当在这个窗口上调用 Show() 方法时,会发生两件事:

1) 如果我调用不带参数的 Show() 方法,则不会发生任何事情。窗口保持隐藏状态,不再显示在桌面上。

2) 如果我调用 Show(callerContainer.id) 之类的方法给它一个目标,则窗口会显示在桌面上,但任务栏中的窗口“指示器”没有重新加载,并且我收到一条错误消息“offsetWidth”属性未定义。

问题:

有谁知道当一个窗口被配置为 CloseAction = Hide 时可以调用任何其他方法来将它“恢复”到桌面,就像第一次创建时一样?

**更新:重现问题的完整代码*** ***

入口点控制器 (DektopController.cs)

[DirectController]
public class DesktopController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [DirectMethod(ShowMask = true)]
    public ActionResult CreateModuleWindow(string callingContainerId, string moduleId)
    {
        //Only AJAX requests are allowed
        if (Request.IsAjaxRequest() == true)
        {
            ControllerHelpers.CreateAndAttachWindow(this, callingContainerId, moduleId);
            return this.Direct();
        }
        else //No direct URL access
        { return new EmptyResult(); }
    }
}

控制器助手

    public static Window GetWindowViewModel(string moduleId)
    {
        // Dynamically instantiate the ViewModel class
        // By convention, the ViewModel that creates the Window is named
        // moduleName + "ViewModel".
        // The ViewModel should also assign the moduleId to the window.ID

        Type type = Type.GetType("App.Web.ViewModels." + moduleId + "ViewModel");

        Object obj = Activator.CreateInstance(type);

        return (Window)obj;
    }

    public static void CreateAndAttachWindow(Controller cont, string callingContainerId, string moduleId)
    {
        Desktop callingContainer = cont.GetCmp<Desktop>(callingContainerId);

        Window moduleWindow = GetWindowViewModel(moduleId);

        if (moduleWindow != null)
        {
            callingContainer.CreateWindow(moduleWindow);
        }
    }

RAZOR 索引文件

@model Ext.Net.Desktop

@{
   ViewBag.Title = "Desktop";
   Layout = "~/Views/Shared/_Desktop.cshtml";
   var X = Html.X();
}

@(
 X.Desktop()
    .ID("MyDesktop")
        .Listeners(l =>
        {
            l.Ready.BroadcastOnBus = "App.Desktop1.Ready";
        })
        .Modules(
            X.DesktopModule()
                .ModuleID("Module1")
                .Shortcut(
                    X.DesktopShortcut()
                        .Name("Module 1")
                        .Handler("loadModuleWindow(App.MyDesktop,'Module1');")
                )
        )
        )

"loadModuleWindow" JAVASCRIPT 文件

function loadModuleWindow(callingContainer, moduleId) {

    //Only create new window if it hasn't been created already
    if (App[moduleId] == undefined) {
        App.direct.CreateModuleWindow(callingContainer.id, moduleId);

        //Set the returned window to the module, by convention, the
        //window.id is the same as the moduleId.
        App[callingContainer.id].getModule(moduleId).setWindow(moduleId);
    } else {
        App[callingContainer.id].getModule(moduleId).run();
    }
}

模块1查看模型文件

public class Module1ViewModel : Window
{
    public Toolbar TopToolBar {get; private set;}
    public TreePanel AssetHierarchy { get; private set; }

    public Module1ViewModel()
    {
        this.ID = "Module1";
        this.Title = "Module1";
        this.Width = 1400;
        this.Height = 600;
        this.Layout = LayoutType.Border.ToString();
        this.CloseAction = CloseAction.Hide;
        this.Stateful = true;
    }
}

【问题讨论】:

    标签: window desktop ext.net


    【解决方案1】:

    有一些问题。

    首先,Module 的 id 和它的 Window 必须是唯一的,它们是独立的组件。

    所以,请更改,例如,在 Module1ViewModel 中。

    this.ID = "Module1_Window"
    

    其次,桌面的 CreateWindow 显示独立于任何模块的窗口,并且 setWindow 调用不足以将窗口附加到模块。我们应该有方便的方法来将一个窗口附加到一个模块,但是,目前,我们没有这样的方法。目前,我可以提出以下解决方案。

    将 loadModuleWindow 函数替换为:

    function loadModuleWindow(callingContainer, moduleId) {
        var module = App[callingContainer.id].getModule(moduleId);
    
        if (!module.win) {
            App.direct.CreateModuleWindow(moduleId, {
                success: function (result) {
                    module.autoRun = true;
                    module.addWindow(function () { return eval(result)[0] });
                }
            });
        } else {
            module.run();
        }
    }
    

    将 CreateModuleWindow 方法替换为:

    [DirectMethod(ShowMask = true)]
    public ActionResult CreateModuleWindow(string moduleId)
    {
        Window moduleWindow = GetWindowViewModel(moduleId);
        moduleWindow.AutoRender = false;
        string moduleWindowCfg = ComponentLoader.ToConfig(moduleWindow);
    
        return this.Direct(moduleWindowCfg);
    }
    

    剩下的不做任何改动。

    有关设计的一些说明。

    通常,桌面的模块不支持动态附加窗口,因为模块应该用作与其窗口不可分割的单元。这意味着模块期望为模块预定义一个窗口。它应该怎么做。您可以创建一个窗口而不将其分配给任何模块,也可以即时创建整个模块。

    【讨论】:

    • 您好丹尼尔,谢谢您的回复。我实际上已经尝试过,但它不起作用。 run() 方法触发 createWindow() 和随后的所有内容,但最后窗口不会在桌面上“重新加载”。我尝试了以下排列。 code App.Desktop1.getModule(moduleId).run(); App.Desktop1.getModule(moduleId).createWindow(); App.Desktop1.getModule(moduleId).shortcutItemClick(); code 但它们都不起作用。
    • 请澄清您在“重新加载”下的意思是什么?没有出现吗?
    • 你好丹尼尔。是的。我使用“重新加载”这个词来区别于简单地显示窗口。正如帖子中提到的,我可以使用 Show(target) 方法,使用桌面作为目标并显示窗口。但是,任务栏上的相关按钮未加载,未重新创建,窗口的最大化/最小化/关闭工具不起作用。我所说的“重新加载”是指将 Window 以其全部功能带回前台,就像它第一次创建时一样。干杯。
    • 另外,为了清楚起见,我应该在回复中提到模块的 run() 方法甚至不显示窗口(如 show() 方法如上所述的窗口本身。
    • 你好丹尼尔。新设计按预期工作。我刚刚发现一个引发错误的错误是您定义了一个没有任何模块的桌面。当您尝试加载第一个模块时,动态生成的 JS 会引发错误。我已经提出了一个错误报告,其中包含您网站中的所有详细信息。目前我已经通过定义一个“虚拟”模块来初始化桌面的模块集合来解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    相关资源
    最近更新 更多