2016-06-15 17 views
2

私のViewModelは、次のようなMultipleSelectionInfo型のプロパティを持っています(わかりやすくするためにPropertyChanged関連コードを削除しましたが、バインディングが機能します):WPF - ItemsControlの項目を含むパネルにテキストボックスを追加する方法

public abstract class MultipleSelectionInfo 
{ 
    // A SelectableObject is made of a bool IsSelected and a string ObjectData 
    public ObservableCollection<SelectableObject<string>> Items 
    { get; set; } 

    public string Others 
    { get; set; } 
} 

私はそのように、これらのプロパティを表示します。

TextBox pushed to the bottom TextBox pushed to the right

私のXAMLは、次のようになります。

<DataTemplate x:Key="PrepControl"> 
     <WrapPanel Orientation="Horizontal" HorizontalAlignment="Left"> 
      <ItemsControl ItemsSource="{Binding Items}"> 
       <ItemsControl.ItemsPanel> 
        <ItemsPanelTemplate> 
         <WrapPanel Orientation="Horizontal"/> 
        </ItemsPanelTemplate> 
       </ItemsControl.ItemsPanel> 
       <ItemsControl.ItemTemplate> 
        <DataTemplate> 
         <StackPanel Orientation="Horizontal"> 
          <CheckBox Content="{Binding ObjectData}" IsChecked="{Binding IsSelected}" Margin="0,6,8,0"/> 
         </StackPanel> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
      </ItemsControl> 

      <TextBox MaxWidth="400" MinWidth="100" 
        MaxHeight="20" Text="{Binding Others}" IsEnabled="{Binding IsOthersSelected}" 
         HorizontalAlignment="Left"/> 
     </WrapPanel> 
    </DataTemplate> 

合計すると、ItemsControl(水平WrapPanel)にMultipleSelectionInfoの項目が表示されていますが、TextBoxが表示されます。最後に、全体をWrapPanelでラップします。

この問題は、TextBoxがWrapPanelsのためにアイテムとうまく整列しないという問題があります。理想的には、ItemsControlのWrapPanelの中​​にTextBoxを追加すると、それが修正されます。しかし、私はそれをすることはできませんでした。

可能ですか?どうすればいいですか?私は喜んでプログラムでコントロール/パネルを操作することを避けるだろう。私が本当にしなければならないことは、私はMVVMにあまり慣れていないので、あなたは説明してくれませんか?あなたは、同じタイプの複数のDataTemplateを持っているときにDataTemplateSelectorを作成し、 Expected display 1 Expected display 2

+2

のItemsSourceは 'のObservableCollection Items'とDataTemplateを使用してい'{Binding ObjectData}'と '{Binding IsSelected}'を呼び出します。それは仕事をするつもりはありません – ASh

+0

あなたは正しいです。私はコードを読みやすくするために簡略化しました。私に更新させてください。 – corentinaltepe

答えて

1

普遍的なアプローチは、一般的にDataTemplateSelector

を作成することです。以下は

は私が達成するために期待するものです各データオブジェクトのプロパティに基づいて適用するDataTemplateを選択する独自のロジックを提供する場合

012与えられた場合、私は OthersアイテムのContentTemplateを変更トリガしようとで

:トリガを介してDataTemplateを選択付き

<DataTemplate x:Key="PrepControl"> 
<ItemsControl ItemsSource="{Binding Items}" Grid.Column="1" Name="Lst"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <WrapPanel Orientation="Horizontal"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <CheckBox Content="{Binding ObjectData}" 
          IsChecked="{Binding IsSelected}" 
          Margin="0,6,8,0"> 
        <CheckBox.Style> 
         <Style TargetType="CheckBox"> 
          <Style.Triggers> 
           <Trigger Property="Content" Value="Others"> 
            <Setter Property="ContentTemplate"> 
             <Setter.Value> 
              <DataTemplate> 
               <StackPanel Orientation="Horizontal"> 
                <TextBlock Text="{Binding}" VerticalAlignment="Center"/> 
                <TextBox Margin="5,0" VerticalAlignment="Center" 
                   MinWidth="50" 
                   IsEnabled="{Binding IsChecked, RelativeSource={RelativeSource AncestorType=CheckBox}}" 
                   Text="{Binding Path=DataContext.Others, ElementName=Lst}"/> 
               </StackPanel> 
              </DataTemplate> 
             </Setter.Value> 
            </Setter> 
           </Trigger> 
          </Style.Triggers> 
         </Style> 
        </CheckBox.Style> 
       </CheckBox> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
</DataTemplate> 


バリアントを

<ItemsControl ItemsSource="{Binding Items}" Grid.Column="1" Name="Lst"> 
    <ItemsControl.Resources> 
     <DataTemplate x:Key="CheckItem"> 
      <CheckBox Content="{Binding ObjectData}" 
        IsChecked="{Binding IsSelected}" 
        Margin="0,6,8,0"/> 
     </DataTemplate> 

     <DataTemplate x:Key="OthersItem"> 
      <StackPanel Orientation="Horizontal"> 
       <CheckBox IsChecked="{Binding IsSelected}" 
          Content="{Binding ObjectData}" 
          Margin="0,6,8,0"/> 
       <TextBox Margin="5,0" VerticalAlignment="Center" 
         MinWidth="50" 
         IsEnabled="{Binding IsSelected}" 
         IsHitTestVisible="True" 
         Text="{Binding Path=DataContext.Others, ElementName=Lst}"/> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.Resources> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <WrapPanel Orientation="Horizontal"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <ContentPresenter Content="{Binding}"> 
       <ContentPresenter.Style> 
        <Style TargetType="ContentPresenter"> 
         <Setter Property="ContentTemplate" Value="{StaticResource CheckItem}"/> 
         <Style.Triggers> 
          <DataTrigger Binding="{Binding Path=ObjectData}" Value="Others"> 
           <Setter Property="ContentTemplate" Value="{StaticResource OthersItem}"/> 
          </DataTrigger> 
         </Style.Triggers> 
        </Style> 
       </ContentPresenter.Style> 
      </ContentPresenter> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
+0

うわー、それはトリックでした!ありがとうございました。 TextBoxがCheckBoxに含まれているため、UXはさらに改善されました(TextBoxを有効にする 'Others' CheckBoxの無効なTextBoxのクリックをクリックすると)。 どうしたらいいか分かりません。もし私が間違っていれば私を修正できますか? コンテンツ(テキスト)が「その他」の場合を除いて、各アイテムは「通常の」CheckBoxとして表示されます。次に、スタイルはTextBoxを追加します。このテキストはItemsコレクションの外側の要素にバインドされます。 私はこれまでと同じようなことを試みましたが、テキストボックスコンテンツのバインドを正しく管理できませんでした。それは今働きます! – corentinaltepe

+1

@corentin、CheckBoxはToggleButtonから派生し、無効なTextBoxを含むすべてのコンテンツがクリック可能になります。私はそれを忘れてしまった。このような動作をしないで私の編集を見てください(TextBoxはCheckBoxテンプレートの一部ではありません) – ASh

関連する問題