0

わかりました、これが私の簡単なシナリオです。概念実証として、TabControlにバインドしている文字列のコレクションがあります。文字列を追加するときに、リージョン名をヘッダーとして、ItemsControlをTabコンテナーに含む新しいタブが必要です。その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

3 に答える 3

2

リージョンに追加するものの少なくとも1つで、region.Activate(stuffIJustAddedToTabsControl)を呼び出す必要があります。タブコントロールとリージョンを同期させます。そうでなければ、それはすべて狂ったように見え、より悪い行動をします。

于 2009-09-23T12:59:41.643 に答える
1

TabControlをリージョンとして機能させますか?そうすれば、そのビューにリージョンを追加することができます。これらのビューにリージョンが必要な場合は、サブ/ネストされたリージョンを作成し、ビューにそのリージョンを挿入するだけです。リージョンを動的に作成する必要はありませんでした...

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

PrismのStockChartsRIは、ビューモデルからタブのヘッダーを直接バインドする方法を示しています。それらはTabPanelのサブクラス(AnimatedTabPanel)を使用しますが、セットアップは同じです。

于 2009-09-24T01:35:57.497 に答える
0

うまくいくものがありますが、アンダーソン・アイメスが何を思いついたのか見てみたいです。

基本的に、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);

  }
于 2009-09-23T14:28:06.337 に答える