与 TabItem 多次使用同一模块

发布于 2024-07-12 10:55:03 字数 556 浏览 7 评论 0原文

这是我的场景:

  1. 具有 1 个 TabControl 和 1 个名为 MenuRegion 的区域的 Shell
  2. 包含每个可用模块(应用程序)的按钮。

我想使用 Prism(WPF 复合应用程序库)实现以下目标:单击其中一个按钮时,我需要向 TabControl 添加一个新的 TabItem,并在该 TabItem 内加载相应模块(应用程序)的单个实例。 一个模块可能会在 TabControl 中出现多次。


我真的很感谢你的回答。 但我不相信您正在使用 Prism (http://www.codeplex.com/CompositeWPF) 你是吗? 我的问题与 Prism 更相关,我现在对其进行了编辑以使其更加清晰。

在 Prism 中,您可以将模块的视图动态加载到区域中。 我不确定在我的场景中如何做到这一点,因为区域是动态设置的。 我该如何命名它们?

谢谢!

Here's my scenario:

  1. Shell with 1 TabControl and 1 region called MenuRegion
  2. MenuRegion contains Buttons for each of the available modules (applications).

I want to achieve the following using Prism (Composite Application Library for WPF): When one of the buttons is clicked, I need to add a new TabItem to the TabControl, and load and individual instance of the corresponding module (application) inside this TabItem.
One module may appear several times in the TabControl.


I really appreciate your answer. But I don't believe you're using Prism (http://www.codeplex.com/CompositeWPF) are you? My question was more related to Prism, and I've edited it to be more clear now.

In Prism you dynamically load modules' views into regions. I am not sure how to do that in my scenario because the regions are to be set dynamically. How would I name them?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吖咩 2024-07-19 10:55:03

我是这个 PRISM 世界的新手(1 周经验:)))并且有相同的要求!
首先,您必须从 此处

我的(可能是你的)问题的解决方案如下:

  • 有 2 个区域(菜单和 tabcontrol - 用于类似 mdi 的行为)

  • tabitem header 必须准备一个用于关闭的按钮(它绑定到一个用于关闭此 tabitem 的命令 - 实际上隐藏此 tabitem)

  • 将事件从菜单项发送到应加载视图的模块(我已根据需要实例化了模块)。 在模块的初始化方法中订阅菜单项发送的事件。 在事件处理方法中,您只需重新显示 tabitem

如果这对您来说是抽象的,我可以向您发送一个我开发的框架应用程序来玩。

I'm new to this PRISM world (1 week experience :)) ) and had the same requirement!
First of all you have to get the Regionextensions from here.

The solution to my (may be your) problem is as follows:

  • have 2 regions (menu and tabcontrol - for mdi like behaviour)

  • tabitem header has to be prepared with a button for closing (which is bound to a command for closing this tabitem-actually hiding this tabitem)

  • send event from menu item to the module which should load the view (I've instantiated the modules on demand). In the module's initialize method subscribe to the event sent by the menu item. In the event handling method you simply re-show the tabitem

If this is to abstract to you I can send you a skeleton application I've developed to play around.

对不⑦ 2024-07-19 10:55:03

我们做了类似的事情,尽管我们已经创建了选项卡项目(没有内容)并根据需要显示/隐藏。 当选项卡项被选择时,我们加载选项卡内容。

private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.OriginalSource != sender) return;

        TabControl tabControl = (TabControl)sender;
        TabItem tabItem = (TabItem)tabControl.SelectedItem;

        if (!tabItem.HasContent)
            AddTabContent(tabItem); // This will cause a refresh once the content is loaded.
        else
            Refresh(tabItem);
    }



private void AddTabContent(TabItem tabItem)
    {
        IOptimusPage page = tabItem.Tag as IOptimusPage;

        //This allows lazy loading of controls
        if (page != null)
        {
            if (!tabItem.HasContent)
            {
                CustomerEngagementUserControl control = page.GetControl(DataContext as CustomerEngagementUIObject, Services);

                tabItem.Content = control;
            }
        }

    }

选项卡项内容在选项卡项标记中指定,使用负责创建内容的页面。

<TabItem
Header="Personal Background"
Style="{StaticResource FirstBreadcrumbTabItem}"
x:Name="PersonalBackgroundTab">
    <TabItem.Tag>
        <Pages:FfnaPersonalBackgroundPage />
    </TabItem.Tag>
</TabItem>

该页面创建控件。

class FfnaPersonalBackgroundPage : IOptimusPage
{
    #region IOptimusPage Members

    public CustomerEngagementUserControl GetControl(CustomerEngagementUIObject dataContext, CustomerEngagementServices services)
    {
        CustomerEngagementUserControl control = new FfnaPersonalBackgroundControl();
        control.DataContext = dataContext;
        control.Services = services;
        return control;
    }

    #endregion
}

您可以使用类似的技术来动态创建选项卡项目。

We do something similar, though we have the tab items already created (with no content) and show/hide as appropriate. When the tab item is selected, then we load the tab content.

private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.OriginalSource != sender) return;

        TabControl tabControl = (TabControl)sender;
        TabItem tabItem = (TabItem)tabControl.SelectedItem;

        if (!tabItem.HasContent)
            AddTabContent(tabItem); // This will cause a refresh once the content is loaded.
        else
            Refresh(tabItem);
    }



private void AddTabContent(TabItem tabItem)
    {
        IOptimusPage page = tabItem.Tag as IOptimusPage;

        //This allows lazy loading of controls
        if (page != null)
        {
            if (!tabItem.HasContent)
            {
                CustomerEngagementUserControl control = page.GetControl(DataContext as CustomerEngagementUIObject, Services);

                tabItem.Content = control;
            }
        }

    }

The tab item content is specified in the tab item tag, using pages which are responsible for creating the content.

<TabItem
Header="Personal Background"
Style="{StaticResource FirstBreadcrumbTabItem}"
x:Name="PersonalBackgroundTab">
    <TabItem.Tag>
        <Pages:FfnaPersonalBackgroundPage />
    </TabItem.Tag>
</TabItem>

The page creates the control.

class FfnaPersonalBackgroundPage : IOptimusPage
{
    #region IOptimusPage Members

    public CustomerEngagementUserControl GetControl(CustomerEngagementUIObject dataContext, CustomerEngagementServices services)
    {
        CustomerEngagementUserControl control = new FfnaPersonalBackgroundControl();
        control.DataContext = dataContext;
        control.Services = services;
        return control;
    }

    #endregion
}

You could use a similar technique to create your tab items on the fly.

傲娇萝莉攻 2024-07-19 10:55:03

我知道回复已经很晚了,但我正在做类似的事情,尽管尚未实现完整的解决方案。

此代码发生在我在演示器中处理的按钮的单击事件上。 该模块在配置文件中定义。

ModuleInfo moduleInfoObject = this.moduleEnumerator.GetModule("ModuleA"); 

Assembly assembly = this.LoadAssembly(moduleInfoObject);

Type type = assembly.GetType(moduleInfoObject.ModuleType);
IModule aModule = this.CreateModule(type);                                    
aModule.Initialize();  


// - - - -Helper Methods - - - -
// - - - LoadAssembly - - -       
private Assembly LoadAssembly(ModuleInfo moduleInfo)
    {            
        string assemblyFile = moduleInfo.AssemblyFile;
        assemblyFile = this.GetModulePath(assemblyFile);

        FileInfo file = new FileInfo(assemblyFile);
        Assembly assembly;

        try
        {
            assembly = Assembly.LoadFrom(file.FullName);
        } 
        catch (Exception ex)
        {
            throw new ModuleLoadException(null, assemblyFile, ex.Message, ex);
        } 

        return assembly;

    } // LoadAssembly(moduleInfo)


// - - - CreateModule - - -
private IModule CreateModule(Type type)
    {
        return (IModule)containerFacade.Resolve(type);            
    } // CreateModule(type)


// - - - GetModulePath - - -
private string GetModulePath(string assemblyFile)
    {
        if (String.IsNullOrEmpty(assemblyFile))
        {
            throw new ArgumentNullException("assemblyFile");
        } // if

        if (Path.IsPathRooted(assemblyFile) == false)
        {
            assemblyFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyFile);
        } // if

        return assemblyFile;
    } // GetModulePath(assemblyFile)

I know it's quite late a response but I am doing something similar, although haven't achieved the full solution yet.

This code happens on the click event of a button which I am handling in the presenter. The module is defined in the config file.

ModuleInfo moduleInfoObject = this.moduleEnumerator.GetModule("ModuleA"); 

Assembly assembly = this.LoadAssembly(moduleInfoObject);

Type type = assembly.GetType(moduleInfoObject.ModuleType);
IModule aModule = this.CreateModule(type);                                    
aModule.Initialize();  


// - - - -Helper Methods - - - -
// - - - LoadAssembly - - -       
private Assembly LoadAssembly(ModuleInfo moduleInfo)
    {            
        string assemblyFile = moduleInfo.AssemblyFile;
        assemblyFile = this.GetModulePath(assemblyFile);

        FileInfo file = new FileInfo(assemblyFile);
        Assembly assembly;

        try
        {
            assembly = Assembly.LoadFrom(file.FullName);
        } 
        catch (Exception ex)
        {
            throw new ModuleLoadException(null, assemblyFile, ex.Message, ex);
        } 

        return assembly;

    } // LoadAssembly(moduleInfo)


// - - - CreateModule - - -
private IModule CreateModule(Type type)
    {
        return (IModule)containerFacade.Resolve(type);            
    } // CreateModule(type)


// - - - GetModulePath - - -
private string GetModulePath(string assemblyFile)
    {
        if (String.IsNullOrEmpty(assemblyFile))
        {
            throw new ArgumentNullException("assemblyFile");
        } // if

        if (Path.IsPathRooted(assemblyFile) == false)
        {
            assemblyFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyFile);
        } // if

        return assemblyFile;
    } // GetModulePath(assemblyFile)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文