Как в Prism (Рекомендации по составным приложениям) получить представления, динамически загружаемые в TabControl?

В приложении Prism v2 я определяю две области, каждая из которых является вкладкой в ​​элементе управления вкладками:

<UniformGrid Margin="10">
    <TabControl>
        <TabItem Header="First" Name="MainRegion" cal:RegionManager.RegionName="MainRegion"/>
        <TabItem Header="Second" Name="SecondRegion" cal:RegionManager.RegionName="SecondRegion"/>
    </TabControl>
</UniformGrid>

В загрузчике загружаются два модуля, и каждый вводит представление в каждый из элементов вкладки:

protected override IModuleCatalog GetModuleCatalog()
{
    ModuleCatalog catalog = new ModuleCatalog();
    catalog.AddModule(typeof(SecondModule.SecondModule));
    catalog.AddModule(typeof(HelloWorldModule.HelloWorldModule));
    return catalog;
}

Теперь, конечно, я хочу выполнить магию развязки, о которой я продолжаю читать, раскомментировать один из модулей и увидеть, что его элемент вкладки вообще не отображается. Вместо этого, напротив, по-прежнему есть два элемента TabItem и один пуст. Это говорит мне о том, что мое приложение по-прежнему тесно связывает данные и пользовательский интерфейс, как в старые плохие дни WinForm.

Итак, что мне нужно сделать здесь, чтобы сделать это динамическим, чтобы пользовательский интерфейс менялся динамически в зависимости от того, какие модули загружены, т.е. чтобы я мог загрузить 10 модулей / представлений в свой загрузчик, и в TabControl автоматически было бы 10 TabItems?

ПРОМЕЖУТОЧНЫЙ ОТВЕТ:

Если я просто сделаю одну область в TabControl:

<TabControl Name="MainRegion" cal:RegionManager.RegionName="MainRegion"/>

а затем загрузите оба элемента управления в MainRegion:

        public void Initialize()
        {
            regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.SecondView));
        }
...
        public void Initialize()
        {
            regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.HelloWorldView));
        }

затем я получаю TabControl с двумя вкладками, на каждой из которых есть представление, чего я и хочу.

Но заголовки TabItem не определены. Как мне динамически определить заголовок (например, не в XAML, а динамически обратно в классы представления)?


person Edward Tanguay    schedule 09.03.2009    source источник


Ответы (3)


Это тоже работает:

public class View : UserControl
{

    public string ViewName { get; set; }

}

а затем в оболочке:

<Window.Resources>        
       <Style TargetType="{x:Type TabItem}" x:Key="TabItemRegionStyle">
                <Setter Property="Header" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.ViewName}" />
       </Style>
</Window.Resources>
    ...
<TabControl cal:RegionManager.RegionName="RightRegion" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" Grid.Column="2" 
                x:Name="RightRegion" ItemContainerStyle="{StaticResource TabItemRegionStyle}" />
person Community    schedule 24.04.2009
comment
Более традиционный подход MVVM переместит свойство ViewName в ViewModel, а затем привязка изменится на: Value = {Binding Path = DataContext.ViewName} - person John Laffoon; 22.05.2011

Хороший.

Вы можете удалить свойство ViwewName в представлении и изменить привязку к значению TabItem на Value = "{Binding DataContext.HeaderInfo}" ... где HeaderInfo - это свойство вашего объекта DataContext - IE бизнес-объект, который элемент вкладки представляет собой. Это немного элегантнее.

person Pete Maher    schedule 15.05.2009

Со своей модификацией вы на правильном пути.

Обычно я добиваюсь заголовка, добавляя объект в область вместо элемента управления и накладывая его на данные вместе с элементом управления.

Этот объект определяет свойство (скажем, MyHeaderProperty), которое я затем использую для привязки к использованию ItemContainerStyle в TabControl.

Я не знаю, есть ли способ добиться этого, не прибегая к подобным уловкам (промежуточный объект и DataTemplate).

person Denis Troller    schedule 13.03.2009