ПРИЗМА + Вкладки = Боль - PullRequest
       33

ПРИЗМА + Вкладки = Боль

4 голосов
/ 23 октября 2009

У меня возникают трудности при попытке создать очень простой сценарий работы с PRISM 2.0 для WPF. Я хочу, чтобы основной рабочей областью моего приложения была TabControl. Каждый раз, когда я добавляю вид, я хочу, чтобы он отображался как TabItem на TabControl.

Звучит легко, правда?

Мой регион, который находится в моем Shell.XAML выглядит так:

<Controls:TabControl 
    Name="MainRegion" 
    cal:RegionManager.RegionName="{x:Static Infrastructure:RegionNames.TabRegion}"
    ItemContainerStyle="{StaticResource ShellTabItemStyle}" />

Стиль: ShellTabItemStyle выглядит так:

<Style x:Key="ShellTabItemStyle" TargetType="{x:Type TabItem}">
    <Setter Property="Header" Value="{Binding Content.DataContext.HeaderInfo, RelativeSource={RelativeSource Self}}" />
</Style>

Это должно установить Header TabItem для свойства HeaderInfo в DataContext представления. (Я получил эту идею из этой статьи ) На мой взгляд DataContext очень простое Presenter, у которого есть свойство HeaderInfo:

public string HeaderInfo = "The Header Text";

На мой взгляд, это простой пользовательский контроль WPF, который выглядит следующим образом:

  <StackPanel>
    <TextBox Text="Hello World" Name="MyTextBox"></TextBox>
    <Image Source="..SomeImage.PNG" Name="MyImage"></Image>
  </StackPanel>

Пока все хорошо. Если я добавляю вид в регион, я получаю элемент управления вкладками и вкладку с текстом, установленным на «Текст заголовка». Моя проблема в том, что на вкладке нет абсолютно никакого контента. Мое представление содержит простые Image и TextBox, но ни один из них не отображается в TabItem. Если я выберу Snoop и посмотрю вокруг, изображения не будет.

Что мне здесь не хватает - есть ли более простой способ?

Ответы [ 3 ]

3 голосов
/ 26 октября 2009

Мне не удалось получить ни одного из предложенных ответов для работы. Обширный поиск в Google тоже не помог. В течение выходных я немного размышлял над этой проблемой, и чем больше я думал об этом, тем больше мне приходило в голову, что в этом подходе есть какой-то запах кода . Вы внедряете представление в свой регион вкладок ... происходит что-то волшебное, и добавляется вкладка ... вам нужно добавить непонятное динамическое связывание с некоторыми стилями XAML, хранящимися где-то в файле, и это может или не может установить текст заголовка , Если какой-то один элемент этого будет немного ошибочным, вы не получите ошибку, но она просто не будет работать.

На мой взгляд, это и хрупко (то есть очень легко сломать) и довольно непроницаемо, если у вас нет глубокого понимания ПРИЗМЫ, модели и XAML. К счастью, есть гораздо более приятный и простой способ сделать это:

Просто создайте представление с именем TabRegionView , которое содержит только пустой TabControl. Вы, вероятно, хотите добавить это в свой Shell.xaml. Создайте событие с именем InjectTabView , которое имеет полезную нагрузку типа UserControl, и подпишитесь на это событие в элементе управления TabRegionView . Когда событие запускается в TabRegionView , вы создаете TabItem вручную и добавляете представление к TabItem следующим образом:

public void TabAdded(UserControl view)
{
    var item = new TabItem();
    item.Content = view;
    item.IsSelected = true;
    item.Header = "Header Text";
    mainTab.Items.Add(item);
}

Когда вы хотите отобразить представление в виде новой вкладки, ваш код выглядит примерно так:

    var view = new View(params);
    _eventAggregator.GetEvent<InjectTabViewEvent>()
        .Publish(view);

Это будет взято TabRegionView , и представление будет добавлено как новая вкладка. Вы можете легко обернуть View в жгут проводов какого-либо типа, который содержит текст заголовка, изображение и bool, чтобы указать, нужно ли автоматически выбирать вкладку.

ИМХО, у этой техники есть двойное преимущество: она дает вам прямой контроль над тем, что происходит, и ей намного легче следовать.

Мне было бы очень интересно узнать мнение по этому поводу у любого PRISM officianados.

2 голосов
/ 23 октября 2009

Если вы используете RegionManager, вам нужно активировать свой вид. Вероятно, есть некоторый фрагмент кода, в котором вы добавляете представление в регион, вам просто нужно сообщить этому региону, чтобы активировать его.

public void AddViewToRegion(IRegion region, object view)
{
     region.Add(view);
     region.Activate(view);
}

Это кажется глупым, но вы получаете поведение, которое видите, если не делаете этого. Я нашел это немного разочаровывающим, но это было достаточно легко исправить. Поведение становится еще более странным, когда вы добавляете несколько вкладок, если вы по крайней мере не активируете первое добавленное представление.

Насколько я понимаю, если вы этого не сделаете, представление никогда не станет частью визуального дерева (это побочный эффект того факта, что TabControl деактивирует (удаляет из визуального дерева), когда вкладка не ' t "впереди". Это хорошо для определенных операций, но делает такие вещи немного шаткими.

0 голосов
/ 13 сентября 2010

Несколько случайных мыслей:

  • попробуйте удалить стиль из TabControl
  • проверить визуальное дерево с помощью инструмента Snoop . Вы должны увидеть ваш TabItem с представлением UserControl под TabControl. Затем вы можете проверить, что не так с этим UserControl и его дочерними элементами (содержимым вашего представления). Возможно, по какой-то причине они скрыты.
  • еще одна вещь, чтобы подумать - RegionAdapter. RegionAdapters отвечает за адаптацию представлений регионов для размещения UIControl.
...