2012-03-01 7 views
0

wpfビジュアル継承にはたくさんの質問がありますが、私が必要とするものに非常に近いものは見つかりません。 CRUDアプリケーションでは、ほとんどのコンポーネントが共通する多くのビュー(実際にはユーザーコントロールです)があります。私はラベル、テキストボックス、および他のコントロールでいっぱいに複数の行と複数の列のグリッドを持っています。たとえば、行2と列2のセルにフォーカスを合わせます。ユーザーが実行しているCRUD操作に応じて、代わりにラベル、テキストボックス、コンボボックスが含まれているか、空です。このサイトでは、スタイルとトリガを使って読み込み操作のために読み込み専用にテキストボックスを作成する方法を他の形式で学習しましたが、私の場合はコントロールタイプを変更する必要があります。確かに私が必要とするすべてのコントロールをオーバーラップさせて可視性を変えることができますが、これが最良のアプローチだとは思わないのです。 別の言葉で言えば、私はレイアウトに使用されるグリッドのほとんどのセルを共有するいくつかのビューを持っていますが、それらは特定の限定されたセル内のいくつかのコンポーネントで異なります。 この場合、あなたは何をしますか?私のフォームでは、共通部分を基底クラスの中に入れ、それから派生することができます。xamlではそれを行うことはできません。私の特別なwpfビジュアル継承が必要です

おかげ フィリッポ

答えて

1

OK、あなたのご意見から、私は各コ​​ンテキストに独自のXAMLファイルを持たせたいと思っていますが、共通のテンプレートを参照するようにしています。それでは、次のようにすることができます:

CommonControlなどの共通テンプレートを設定します。XAML:

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="*"/> 
    </Grid.ColumnDefinitions> 
    <Rectangle Grid.Row="0" Grid.Column="0" Fill="Yellow" /> 
    <TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="15" Text="This is some fixed text"/> 
    <ComboBox Grid.Row="0" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center"/> 
    <StackPanel Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center"> 
     <CheckBox>My first checkbox</CheckBox> 
     <CheckBox>My second checkbox</CheckBox> 
    </StackPanel> 
    <ContentControl Grid.Row="1" Grid.Column="1" Content="{Binding Path=SpecificPart1, RelativeSource={RelativeSource AncestorType=UserControl}}"/> 
    <Ellipse Grid.Row="1" Grid.Column="2" Fill="Blue"/> 
</Grid> 

これはコンテキスト固有のUIが表示されるグリッドの行1、列1(下部中央のウィンドウ)を除いて、すべてのグリッド位置に共通のUIを構成する様々なUI要素を有します。内の複数の位置がある場合

public object SpecificPart1 
    { 
    get { return this.GetValue(SpecificPart1Property); } 
    set { this.SetValue(SpecificPart1Property, value); } 
    } 
    public static readonly DependencyProperty SpecificPart1Property = DependencyProperty.Register(
     "SpecificPart1", typeof(object), typeof(CommonControl), new PropertyMetadata(false)); 

:背後にあるコードで今すぐ

は、あなたがテンプレートに供給されるコンテキスト固有のUIを許可するようにした依存関係オブジェクトをCommonControl.xaml.cs設定しましたコンテキスト固有のUIを配置したい場合は、もう一方の依存プロパティをここに追加することができます。

他の多くのXAMLファイルを好きなだけ設定することができます。これらのファイルはすべてこれを参照し、独自のUIを挿入してさまざまな部分に移動します。ここに緑の斜体のテキストを置く例があります。 In MySpecificControl.xaml:

<my:CommonControl> 
     <my:CommonControl.SpecificPart1> 
      <TextBlock Foreground="DarkGreen" FontStyle="Italic" FontSize="14">This is my context specific UI</TextBlock> 
     </my:CommonControl.SpecificPart1> 
    </my:CommonControl> 
0

あなたがトリガーとContentControlにを使いたいように聞こえます。どのタイプのコントロールを表示するかは正確には分かりませんが、たとえば、 "ConditionValue1"または "ConditionValue2"という値をとり、別のUI依存関係を表示するプロパティ "Condition"それがされている値その上、あなたはこのようにXAMLを使用することができます。

<ContentControl Grid.Row="2" Grid.Column="2"> 
     <ContentControl.Style> 
      <Style> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding Condition}" Value="ConditionValue1"> 
         <Setter Property="ContentControl.Template"> 
          <Setter.Value> 
           <ControlTemplate> 
            [ First control goes here ] 
           </ControlTemplate> 
          </Setter.Value> 
         </Setter> 
        </DataTrigger> 
        <DataTrigger Binding="{Binding Condition}" Value="ConditionValue2"> 
         <Setter Property="ContentControl.Template"> 
          <Setter.Value> 
           <ControlTemplate> 
            [ Second control goes here ] 
           </ControlTemplate> 
          </Setter.Value> 
         </Setter> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </ContentControl.Style> 
    </ContentControl> 

可視性を使用しての上に本の大きな利点は、それらが必要なときのコントロールにのみロードされることで、さまざまなものが適所に置かれたとき、古いものは自由にアンロードできます。 Visibility = Collapsedの場合、コントロールはまだ読み込まれ、バックグラウンドでハングします。

0

まあ、私は間違いなくDataTemplatesを見ています。

DataTypeに基づいてテンプレートを選択するだけのシンプルな要件の場合は、すべて設定されています。たとえば、次のようなXAMLを使用して、正しいテンプレート(TextBoxまたはDatePicker) stringDateTimeの組み合わせのオブジェクトのコレクション。

<MyControl.Resources> 
    <DataTemplate DataType="{sys:String}"> 
    <TextBox Text="{Binding}" /> 
    </DataTemplate> 

    <DataTemplate DataType="{sys:DateTime}"> 
    <DatePicker Date="{Binding}" /> 
    </DataTemplate> 
</MyControl.Resources> 

<ItemsControl Items="{Binding MyListOfObjects}" /> 

あなたがタイプするだけの外側に追加のロジックが必要な場合は、DataTemplateSelectorに見えることになるでしょう。たとえば、複雑なオブジェクトのコレクションと、その複雑なオブジェクト内のいくつかのプロパティで、どちらを選択するかを決定する場合は、DataTemplateSelectorを使用する必要があります。

<MyControl.Resources> 
    <DataTemplate x:Key="TextViewTemplate"> 
    <StackPanel Orientation="Horizontal"> 
     <Label Content="Name:" /> 
     <TextBox Text="{Binding Path=Name}" /> 
    </StackPanel> 
    </DataTemplate> 

    <DataTemplate x:Key="TextUpdateTemplate"> 
    <StackPanel Orientation="Horizontal"> 
     <Label Content="Name:" /> 
     <TextBox Text="{Binding Path=Name}" IsReadOnly="True" /> 
    </StackPanel> 
    </DataTemplate> 

    <local:MyDataTemplateSelector x:Key="MySelector" 
    ManagerTemplate="{StaticResource TextUpdateTemplate}" 
    EmployeeTemplate="{StaticResource TextViewTemplate}" /> 
</MyControl.Resources> 

<ItemsControl Items="{Binding Employees}" 
       ItemTemplateSelector="{StaticResource MySelector}" /> 


public MyDataTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate ManagerTemplate { get; set; } 
    public DataTemplate EmployeeTempalte { get; set; } 

    public override DataTemplate SelectTemplate(object item, 
     DependencyObject container) 
    { 
     switch (UserClass.UserLevel) 
     { 
      case UserLevel.Manager: 
       if (ManagerTemplate != null) 
        return ManagerTemplate; 
       break; 

      case UserLevel.Employee: 
       if (EmployeeTemplate != null) 
        return EmployeeTemplate; 
       break; 

      default: 
       throw InvalidOperationException("Invalid enumeration value."); 
     } 

     return base.SelectTemplate(item, container); 
    } 
} 

選択ロジックの多くは、単に似たテンプレートに適用し、追加のプロパティを暴露することができますので、DataTemplateSelector sは非常にまれに使用されている...これがこれを行うためのひとつの方法であることに注意してください。たとえば、このセレクタを使用する代わりに、単に「IsEditable」プロパティを公開し、それをIsReadOnly DependencyPropertyにバインドすることができます。しかし、これはその使用法を示す単なる例でした。とにかく、助けてくれることを願う。

+0

申し訳ありませんが、あなたの解決策はよく分かりません。そこに共通のコントロールはどこにありますか?私が探しているのは、すべてのビューで使用されているすべてのコントロールを(おそらくテンプレート内に)書き込んだり、それぞれのユースケースに対して複数のビューを持って基本テンプレートを追加したいものだけを指定する方法です。この目標を達成するための簡単な方法はありますか? – Filippo

+0

私はあなたの質問を誤解したかもしれません。あなたはそれでより明確になることができますか?今のところ立っているので、私の答えに混乱しているのは、あなたのコメントに対する私の混乱です。 –

+0

MVVMのシナリオで私は読書のための1つの編集のために、1つは作成のために、もう1つは特別なケースを作成するために、eccを持っています。これらのすべてのビューは、コンポーネントのほとんどの部分を軽微な違いで共有しています。共通部分はどこに置くことができますか?私はCRUD操作に適応する独自のxamlファイルを望んでいません。他のxamlファイルの共通コンポーネントを何らかの形で継承しているxamlファイルがもっと欲しいです。テンプレート化が正しい答えかもしれませんが、私はいくつかの例が必要です。 – Filippo

関連する問題