如何在Ext.Net中显示“关闭”的桌面窗口?

时间:2013-06-28 04:29:48

标签: window desktop ext.net

状况:

我正在使用Desktop组件开发一个Ext.Net Web App,我在第一次创建Window时遇到了麻烦。

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

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

处理程序函数“loadModuleWindow”然后有责任决定是否必须首次创建Window,或者是否已经创建了Window,只需要再次显示:

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();
    }
}

创建桌面并首次调用Module时,将调用代码隐藏方法“CreateModuleWindow”,并将Window返回给客户端。

窗口设置为:

window.CloseAction = CloseAction.Hide;

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

正如您可能已经猜到的那样,使用Handler(“loadModuleWindow”)的目的是在Window加载一次之后避免服务器调用。

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

1)如果我在没有参数的情况下调用Show()方法,则没有任何反应。窗口保持隐藏状态,并且不会再显示在桌面上。

2)如果我调用Show(callerContainer.id)这样的方法给它一个目标,那么桌面上会显示Window,但是任务栏中的窗口“指示符”没有重新加载,我得到一个错误,说明“offsetWidth”属性未定义。

问题:

有没有人知道在使用CloseAction配置窗口时可以调用的任何其他方法=隐藏,以便在第一次创建时将其“恢复”到桌面?

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

ENTRY POINT CONTROLLER(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 INDEX FILE

@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 FILE

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();
    }
}

MODULE1查看模型文件

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;
    }
}

1 个答案:

答案 0 :(得分:0)

有一些问题。

首先,Module及其Window的ID必须是唯一的,它们是独立的组件。

因此,请更改,例如,在Module1ViewModel。

this.ID = "Module1_Window"

其次,Desktop的CreateWindow独立于任何模块显示一个Window,而setWindow调用不足以将Window附加到Module。我们应该有方便的方法将Window附加到模块,但是,目前我们没有这样的方法。目前,我可以建议以下解决方案。

将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);
}

保留其他内容而不做任何更改。

有关设计的一些注意事项。

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