Добавить составной регион WPF во время выполнения - PullRequest
0 голосов
/ 23 сентября 2009

Хорошо, вот мой простой сценарий. У меня есть коллекция строк, которые я связываю с TabControl в качестве доказательства концепции. Когда я добавляю строки, я хочу новую вкладку с именем региона в качестве заголовка и ItemsControl в контейнере вкладок. Этот ItemsControl должен определять новый регион.

        <TabControl  x:Name="tabDemo" ItemsSource="{Binding DynamicRegions}" >
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}" />
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <ItemsControl cal:RegionManager.RegionName="{Binding}" ItemsSource="{x:Null}">

                </ItemsControl>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>

Оттуда я добавляю строки в коллекцию. Вкладки отображаются нормально, но при попытке позвонить

   private void AddDynamicRegion(object arg)
  {
     var newRegionName = "Region" + (DynamicRegions.Count + 1).ToString();
     DynamicRegions.Add(newRegionName);
  }

  private void AddRandomRegionContent(object arg)
  {
     if (string.IsNullOrEmpty(SelectedRegion) )
        return; 

     Debug.WriteLine("Injected "  + RegionContent + " into " + SelectedRegion);

     var newContent = new TextBlock() { Text = RegionContent };
     _regionManager.RegisterViewWithRegion(SelectedRegion,() => newContent );

     _regionManager.Regions[SelectedRegion].Activate(newContent);
  }

Выдает либо исключение, что регион не существует, либо исключение, при котором не удалось создать регион, и мой ItemsControl.ItemsSource уже установлен. Я действительно не ожидал, что это будет работать из коробки, но есть ли способ, которым я могу создать динамические области и внедрить их во время выполнения?

Обновление: вызов RegisterViewWithRegion фактически внедряет мой текстовый блок ... но при этом происходит странное поведение между вкладками.

Я изменил его, чтобы я мог выбрать регион и текст, который я хочу добавить. Это всегда работает для первого региона, который я создаю, но после этого переключение между вкладками просто показывает материал, который я добавил в первый регион. Элемент управления вкладками повторно использует мою таблицу данных на нескольких вкладках? Я включил весь свой код из ViewModel. DynamicRegions - это просто ObservableCollection

Ответы [ 4 ]

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

Вам нужно вызвать region.Activate (stuffIJustAddedToTabsControl) хотя бы для одной из вещей, которые вы добавляете в регион. Я получу вкладку управления и регион в синхронизации. В противном случае все выглядит сумасшедшим и ведет себя хуже.

1 голос
/ 24 сентября 2009

Будет ли работать TabControl регион для вас? Таким образом, вы можете просто добавить регионы в это представление. Если этим представлениям нужен регион, просто создайте вложенный / вложенный регион и просмотрите его. Мне действительно никогда не нужно было динамически создавать регионы ...

     <TabControl cal:RegionManager.RegionName="TabRegion" x:Name="tabDemo" ItemsSource="{Binding Something}" >
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}" />
            </DataTemplate>
        </TabControl.ItemTemplate>
     </TabControl>

StockChartsRI в Prism показывает, как вы можете связать заголовок вкладки прямо из вашей модели представления. Они используют подкласс TabPanel (AnimatedTabPanel), но установка такая же.

0 голосов
/ 03 октября 2009

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

0 голосов
/ 23 сентября 2009

Хорошо, у меня есть кое-что, что работает, но я хотел бы посмотреть, что придумает Андерсон Аймс.

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

  private void AddDynamicRegion(object arg)
  {
     var newRegionName = "Region" + (DynamicRegions.Count + 1).ToString();
     DynamicRegions.Add(newRegionName);

     var tabItem = View.tabDemo.ItemContainerGenerator.ContainerFromIndex(DynamicRegions.Count - 1) as TabItem;
     var newRegionContainer = new ItemsControl();
     RegionManager.SetRegionName(newRegionContainer,newRegionName);
     RegionManager.SetRegionManager(newRegionContainer, _regionManager);
     tabItem.Content = newRegionContainer;


  }

Итак, во вставке я могу это сделать, и все отображается в правильном регионе. Интересно, а есть ли лучший способ сделать это?

  private void AddRandomRegionContent(object arg)
  {

     if (string.IsNullOrEmpty(SelectedRegion) )
        return; 

     Debug.WriteLine("Injected "  + RegionContent + " into " + SelectedRegion);

     var newContent = new TextBlock() { Text = RegionContent };
     var region = _regionManager.Regions[SelectedRegion];
     if (region == null)
     {
        Debug.WriteLine("Couldn't find region");
        return;
     }

     region.Add(newContent);
     region.Activate(newContent);

  }
...