3

私は WPF を使用してアプリケーションを作成しています。その一部には、カスタムの社内デバイスを構成するために使用されるさまざまなファイルをユーザーが管理することが含まれます。同じ TabControl 内のタブでさまざまな種類の構成を操作できるようにする必要があります。つまり、TabItems のコンテンツを動的に生成する必要があります。ControlTemplates でこれを行いたいのですが、まだ機能するテンプレートを取得できていません。Window リソースで定義された「pendantConfigurationTabItemTemplate」という ControlTemplate があり、次のコードを使用してテンプレート (アクセスする必要がある名前付きアイテムを含む) を TabItems に適用し、それらを親 TabControl に追加します。

<ControlTemplate x:Key="pendantConfigurationTabItemTemplate" TargetType="TabItem">
    <StackPanel Orientation="Vertical">
        <my:PendantConfigurationFileEditor x:Name="configurationEditor"/>
        <StackPanel Style="{StaticResource defaultOkCancelButtonsContainerStyle}">
            <Button Style="{StaticResource defaultOkCancelButtonStyle}"/>
            <Button Style="{StaticResource defaultOkCancelButtonStyle}" Click="OkButton_Click"/>
        </StackPanel>
    </StackPanel>
</ControlTemplate>

コードビハインド:

TabItem ConfigTab = new TabItem();

switch (ConfigFile.Device)
{
  case DeviceType.PENDANT:
{
  ControlTemplate TabTemplate = Resources["pendantConfigurationTabItemTemplate"] as ControlTemplate;

  ConfigTab.Template = TabTemplate;
  ConfigTab.ApplyTemplate();

  object Editor = TabTemplate.FindName("configurationEditor", ConfigTab);

  PendantConfigurationFileEditor ConfigFileEditor = Editor as PendantConfigurationFileEditor;

  ConfigFileEditor.PendantConfiguration = DeviceConfig;

  break;
}
default:
  /* snipped */
  return;
}

ConfigTab.Header = ConfigFile.ConfigurationName;

this.EditorTabs.Items.Add(ConfigTab);
this.EditorTabs.SelectedIndex = this.EditorTabs.Items.Count - 1;

ただし、プログラムを実行するたびに、タブコントロールにタブが追加されず、代わりにタブコントロールが(一見)テンプレートのコンテンツに置き換えられるかカバーされます。誰かがこれで私を助けてくれますか?

事実上、私がやりたいことは、WPF テンプレートを TabItem ファクトリとして使用することです

4

1 に答える 1

5

TabControl.ItemsSourceさらに、DataTemplatesは、事実上、求めている「ファクトリとしてのテンプレート」ソリューションですが、現在のソリューションとは少し異なるアプローチが必要です。

TabItemを作成してテンプレート化し、Items.Addを呼び出すための手続き型コードを記述するのではなく、ItemsSourceプロパティとデータバインディングを使用します。これにより、WPFはIt​​emsSource内のオブジェクトごとにTabItemを作成します。次に、ContentTemplateSelectorを使用して、適切な基準(Deviceプロパティなど)に従って、このタブに表示されるオブジェクトに適切なテンプレートを選択できます。ただし、この場合は、ControlTemplatesではなくDataTemplatesを使用します。

セレクターは次のようになります。

public class DeviceTypeSelector : DataTemplateSelector
{
  public DataTemplate PendantTemplate { get; set; }
  public DataTemplate DefaultTemplate { get; set; }

  public override SelectTemplate(object item, DependencyObject container)
  {
    ConfigFile cf = (ConfigFile)item;
    switch (cf.Device)
    {
      case DeviceType.Pendant: return PendantTemplate;
      default: return DefaultTemplate;
    }
  }
}

次のようにXAMLでインスタンス化されます。

<local:DeviceTypeSelector x:Key="dts"
                          PendantTemplate="{StaticResource pt}"
                          DefaultTemplate="{StaticResource dt}" />

(ここで、ptとdtは、リソースの他の場所で定義された適切なDataTemplatesです)。

最後に、TabControlは次のようになります。

<TabControl Name="EditorTabs"
            ContentTemplateSelector="{StaticResource dts}" />

そして、それを次のように設定しますEditorTabs.ItemsSource = myConfigFiles;(または、DataContextからXAMLのItemsSourceを取得させる方がよいでしょう)。

また、TabItemsのヘッダーを設定することもできます。これを行うには、HeaderプロパティにSetterを指定してTabControl.ItemContainerStyleを使用します。これは次のようになります。

<TabControl ...>
  <TabControl.ItemContainerStyle>
    <Style TargetType="TabItem">
      <Setter Property="Header" Value="{Binding ConfigurationName}" />
    </Style>
  </TabControl.ItemContainerStyle>
</TabControl>

(ちなみに、ContentTemplateSelectorをインライン化することもできます。ほとんどの場合、小さなチャンクで表示するために、リソースに分割しました。)

于 2009-12-29T01:21:06.907 に答える