2015-10-01 8 views
9

3レベルのグループ化を持つコレクションビューソースを持つWPF Datagridがあります。すべてのコンテンツが折りたたまれているときにエキスパンダーを非表示にする

私はそれがこのようになっていることを、このような3頭のパンダ使用するデータグリッドをスタイリングしている:

Level 1 Expander 
<content> 
    Level 2 Expander 
    <content> 
     Level 3 Expander 
     <content> 

レベル2およびレベル1は、グループのちょうどタイトル

ある私が許可する第二の制御を持っているがレベル3のエクスパンダを背後のオブジェクトのブール型「IsVisible」プロパティにバインドすることによって動作するレベル3のアイテムを表示および非表示にします。

 <!-- Style for groups under the top level. this is the style for how a sample is displayed --> 
     <GroupStyle> 
      <GroupStyle.ContainerStyle> 
       <Style TargetType="{x:Type GroupItem}"> 
        <Setter Property="Margin" Value="0,0,0,0" /> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="{x:Type GroupItem}"> 

           <!-- The parent control that determines whether or not an item needs to be displayed. This holds all of the sub controls displayed for a sample --> 
           <Expander Margin="2" 
              Background="{Binding Path=Name, 
                   Converter={StaticResource SampleTypeToColourConverter}}" 
              IsExpanded="True" 
              Visibility="{Binding Path=Items[0].IsVisibleInMainScreen, 
                   Converter={StaticResource BoolToVisibilityConverter}}"> 

この方法は幻想的にうまく機能します。

もつとも

ユーザーがレベル3エキスパンダー内のすべてのアイテムを選択解除した場合、レベル2のエキスパンダヘッダは、依然として価値のある不動産を目に見えるデータのグループのヘッダを示すまで使用されることを意味する表示。私が望む何

は、その子コントロールにレベル2エキスパンダーの可視性を結合して言う「すべての子どもが表示されている場合は、エキスパンダーを表示し、それ以外の場合は崩壊」

が可能これはするための方法ですか?

+1

*すべての子が表示されている場合はエキスパンダーを表示し、そうでない場合はコンバータタスクのように表示されます。あなたはすでにプロパティ 'IsVisibleInMainWindow'を持っています。子供が倒れたときにそれを変更します。注: 'Items'は' ObservableCollection'でなければなりません。 – Sinatr

+0

あなたは私たちにすべてのエクスパンダを含むより完全なxamlを与えることができますか? –

+0

私はもっとxamlが必要だと思います。 – PScr

答えて

3

で最初の項目を変換するために使用されます。あなたがあまりにも多くのグループを持っていない場合、これはトリックを行う必要があります。

私はちょうどGroupItem ControlTemplateにこのトリガーを追加しました:

<ControlTemplate.Triggers> 
    <DataTrigger Binding="{Binding ElementName=IP, Path=ActualHeight}" Value="0"> 
     <Setter Property="Visibility" Value="Hidden"/> 
     <Setter Property="Height" Value="1"/> 
    </DataTrigger> 
</ControlTemplate.Triggers> 

するとゼロに低下ActualSizeItemsPresenter(IP)は、それがほとんどヘッダを崩壊します。

なぜほとんどですか?

コントロールが初期化されると、結合が発生する前に、ItemPresenter ActualHeightが0であるとVisibilityCollapsedに設定されている場合、ItemPresenterは全くレンダリングされません。

Visibility.Hiddenを使用すると、ItemsPresenterはレンダリングフェーズに移動して測定できます。 私はHeightを0.4 pxに落としましたが、これはデバイスに依存すると思われます。

+0

純粋なxamlでほとんど完璧に機能していたので、私はこの答えを選びました。これは私が思うには最も簡単な方法です –

1

これはあなたのニーズに合わせて具体的に実装する必要がありますが、グリッドコントロールのオーバーライドを使用してメンバーの動的グリッド割り当てを作成しています親グループボックスを非表示にします。

また
public bool AreChildrenVisible { get { return _children.Any(x=>x.IsVisibleInMainScreen); } } 

、パス:

public class DynamicLayoutGrid : Grid 
{ 

     protected override void OnInitialized(EventArgs e) 
     { 
       //Hook up the loaded event (this is used because it fires after the visibility binding has occurred) 
      this.Loaded += new RoutedEventHandler(DynamicLayoutGrid_Loaded); 

      base.OnInitialized(e); 
     } 


     void DynamicLayoutGrid_Loaded(object sender, RoutedEventArgs e) 
     { 
      int numberOfColumns = ColumnDefinitions.Count; 
      int columnSpan = 0; 
      int rowNum = 0; 
      int columnNum = 0; 
      int visibleCount = 0; 

      foreach (UIElement child in Children) 
      { 
       //We only want to layout visible items in the grid 
       if (child.Visibility != Visibility.Visible) 
       { 
        continue; 
       } 
       else 
       { 
        visibleCount++; 
       } 

       //Get the column span of the element if it is not in column 0 as we might need to take this into account 
       columnSpan = Grid.GetColumnSpan(child); 

       //set the Grid row of the element 
       Grid.SetRow(child, rowNum); 

       //set the grid column of the element (and shift it along if the previous element on this row had a rowspan greater than 0 
       Grid.SetColumn(child, columnNum); 

       //If there isn't any columnspan then just move to the next column normally 
       if (columnSpan == 0) 
       { 
        columnSpan = 1; 
       } 

       //Move to the next available column 
       columnNum += columnSpan; 

       //Move to the next row and start the columns again 
       if (columnNum >= numberOfColumns) 
       { 
        rowNum++; 
        columnNum = 0; 
       } 
      } 

      if (visibleCount == 0) 
      { 
       if (this.Parent.GetType() == typeof(GroupBox)) 
       { 
        (this.Parent as GroupBox).Visibility = Visibility.Collapsed; 
       } 
      } 
     } 
    } 
3

あなたがスタイルのMVVMの並べ替えを使用していると仮定すると、あなたは子供たちのすべてが見えない場合はfalseを返し、あなたのグループオブジェクトのプロパティに代わりに結合することができますグループ内のすべてのサブアイテムの集計ステータスに応じてVisibilityを返すためのConverterクラスによるアイテムのコレクション。

0

IMultiValueConverter実装を使用して、アイテムを可視性に変換します。 IsVisibleInMainScreenプロパティのすべての項目がtrueを返すと、コンバータはhiddenをvisibleに戻します。

同じ場所にコンバータを使用するには、Uは、私はあなたの目標を達成するために、むしろシンプルでクリーンな方法で、まだ完璧ではないが、見つかった元の例

関連する問題