2015-02-23 18 views
3

每個DataGrid的高度應取決於:如何動態地在MVVM中的一個StackPanel中設置Extenders內的3個DataGrid的高度?

  1. 是其他擴展器擴展
  2. DataGrid中有多少行有
  3. 如果其他填充劑有擴展,有多少行其他的DataGrid有。
  4. 高度StackPanel中的填充劑是

所有擴展器應始終可見。

如果例如只打開最上面的Extender和它的DataGrid有100行,DataGrid的高度應該幾乎是StackPanel的高度,但在底部,另外兩個Extender應該是可見的,並且最上面的DataGrid可滾動。

當打開2個或3個擴展器時,如果DataGrid中有足夠的數據,則StackPanel應該是「滿」。

enter image description here

我試圖綁定的高度屬性(最下面的擴展Objec信息)

<Expander Header="Object information" IsExpanded="{Binding ObjectInformationExpanded}"> 
     <DataGrid Name="ObjectInformationGrid" CanUserAddRows="False" CanUserResizeColumns="True" CanUserSortColumns="True" IsReadOnly="True" 
       ItemsSource="{Binding SelectedObjectAttributes}" AutoGenerateColumns="False" 
        Height="{Binding ObjectInformationHeight, Mode=TwoWay}" 
        ScrollViewer.CanContentScroll="True" 
        ScrollViewer.VerticalScrollBarVisibility="Visible"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Header="Field" Binding="{Binding Item1}" /> 
       <DataGridTextColumn Header="Value" Binding="{Binding Item2}" /> 
      </DataGrid.Columns> 
     </DataGrid> 
</Expander> 

但現在我的ViewModel有大量的代碼是與演示(查看),仍然沒」將StackPanel的高度放入計算中。相反,我設置了硬編碼的雙值,這不是一個好的解決方案。

下面是簡單的代碼位,更新綁定的高度屬性(這裏至上的DataGrid只)當擴展器打開/關閉和DataGrid綁定集合改變:

private void UpdateHeights() 
    { 
     if (SelectedObjectsExpanded == true) 
     { 
      if (_selectedObjects.Count == 0) 
      { 
       SelectedObjectsHeight = double.NaN; 
      } 
      else if (_selectedObjects.Count < 8) 
      { 
       SelectedObjectsHeight = 100; 
      } 
      else 
      { 
       if (ObjectInformationExpanded && SelectedSwitchesExpanded) 
        SelectedObjectsHeight = 100; 
       else 
        SelectedObjectsHeight = 200; 
      } 
     } 
     //... 

謝謝!

回答

2

會像this工作?

基本思想是將所有3 Expanders放在包含3行的Grid中,並將每行的RowDefinition.Height綁定到Expander.IsExpanded。如果擴展器摺疊(僅佔用所需空間),則使用Converter將值設置爲Auto;如果擴展器佔用全部剩餘空間,則使用*。如果將多個行設置爲*高度,則在它們之間均勻分享空間)。

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="{Binding IsExpanded, ElementName=Expander1, Converter={x:Static MyBoolToGridSizeConverter}}" /> 
     <RowDefinition Height="{Binding IsExpanded, ElementName=Expander2, Converter={x:Static MyBoolToGridSizeConverter}}" /> 
     <RowDefinition Height="{Binding IsExpanded, ElementName=Expander3, Converter={x:Static MyBoolToGridSizeConverter}}" /> 
    </Grid.RowDefinitions> 

    <Expander Grid.Row="0" x:Name="Expander1"> 
     <DataGrid /> 
    </Expander> 
    <Expander Grid.Row="1" x:Name="Expander2"> 
     <DataGrid /> 
    </Expander> 
    <Expander Grid.Row="2" x:Name="Expander3"> 
     <DataGrid /> 
    </Expander> 
</Grid> 
public class BoolToGridSizeConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, 
     object parameter, CultureInfo culture) 
    { 
     if (value is bool && (bool)value) 
      return new GridLength(1, GridUnitType.Star); 

     return GridLength.Auto; 
    } 

    public object ConvertBack(object value, Type targetType, 
     object parameter, CultureInfo culture) 
    { 
     // this is not needed 
    } 
} 
+0

聽起來就像是更好的主意,而不是使用'StackPanel'。但是,我想'DataGrid'的'ScrollViewers'不會顯示出來,因爲網格有無限高度? – Herdo 2015-02-26 08:06:55

+0

感謝您的回答@Rachel!我在晚上時間(幾個小時內)評估這一點。如果@Herdo的擔憂是有道理的,如果您有時間,請重複您的答案。 – 2015-02-26 11:32:28

+0

@Herdo如果Expanders限制孩子的大小,我會忘記,但如果這是一個問題,您可以輕鬆地將DataGrid的高度綁定到Expander的高度。或者你可以嘗試將它們包裹在限制高度的面板中,如「Grid」。你也可以將它們包裝在一個'ScrollViewer'中,但這會禁用DataGrid的虛擬化,所以我不會建議,除非事先知道你的Grid不會有很多數據。 – Rachel 2015-02-26 13:23:15

相關問題