同一模块多次为TabItems

时间:2009-01-16 19:55:06

标签: wpf prism

这是我的情景:

  1. 带有1个TabControl的Shell和名为MenuRegion的1个区域
  2. MenuRegion包含每个可用模块(应用程序)的按钮。
  3. 我想使用Prism(WPF的复合应用程序库)实现以下功能:当单击其中一个按钮时,我需要向TabControl添加一个新的TabItem,并加载相应模块的单个实例(应用程序)在这个TabItem里面。 一个模块可能会在TabControl中出现多次。


    我非常感谢你的回答。但我不相信你正在使用棱镜(http://www.codeplex.com/CompositeWPF)是吗?我的问题与Prism有关,我现在对它进行了更清晰的编辑。

    在Prism中,您可以将模块的视图动态加载到区域中。我不确定如何在我的场景中执行此操作,因为要动态设置区域。我怎么称呼它们?

    谢谢!

3 个答案:

答案 0 :(得分:1)

我是这个PRISM世界的新手(1周经验:)))并且有相同的要求! 首先,你必须从here获得Regionextensions。

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

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

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

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

如果要抽象给你,我可以寄给你一个我开发的骨架应用程序。

答案 1 :(得分:0)

我们做了类似的事情,虽然我们已经创建了标签项(没有内容)并且适当地显示/隐藏。选中选项卡项后,我们会加载选项卡内容。

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
}

您可以使用类似的技术动态创建标签项。

答案 2 :(得分:0)

我知道这是一个很晚的回应,但我正在做类似的事情,虽然还没有达到完整的解决方案。

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

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)