2016-08-18 27 views
0

如何獲得ListView標題的高度爲GridView?它甚至有可能嗎?使用GridView獲取ListView標題的高度

我需要根據ListView的標題高度來設置一個控件的高度,所以我開始編寫Converter。問題是我無法訪問實際的高度。

Visual Studio的調試器顯示GridView有一個名爲HeaderRowPresenter的屬性,該屬性又具有屬性ActualHeight。但我無法訪問它,HeaderRowPresenter似乎被保護或私密。

所有其他ColumnHeader*性質(ColumnHeaderContainerStyleColumnHeaderTemplate等)是null此對象上,同用於在ColumnsHeader*所有屬性(除了String即報頭的內容)。

順便說一句:我試圖解決different problem和我目前的做法讓我這樣做,所以也許我採取了錯誤的方式。

回答

0

好吧,我已經找到了解決辦法,但我不是很驕傲,因爲它使用反射:

我寫了一個Converter,需要一個ViewListView爲值和參數,並返回高度頭的區別:

public class HeightSyncConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     GridView gvLocal = value as GridView; 
     ListView lvOther = parameter as ListView; 

     if(gvLocal == null || lvOther == null) 
     { 
      return 0; 
     } 
     GridView gvOther = (GridView)lvOther.View; 
     try 
     { 
      // get the non-public HeaderRowPresenter property 
      GridViewHeaderRowPresenter hrpLocal = (GridViewHeaderRowPresenter)gvLocal.GetType().GetProperty("HeaderRowPresenter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(gvLocal); 
      GridViewHeaderRowPresenter hrpOther = (GridViewHeaderRowPresenter)gvOther.GetType().GetProperty("HeaderRowPresenter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(gvOther); 

      if(hrpLocal == null || hrpOther == null) 
      { 
       return 0; 
      } 

      // Only works if the other ListView's header is higher than the local one's 
      if(hrpLocal.ActualHeight > hrpOther.ActualHeight) 
      { 
       return 0; 
      } 
      return hrpOther.ActualHeight - hrpLocal.ActualHeight; 
     } 
     catch(TargetInvocationException) { } 

     return 0; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return null; 
    } 
} 

然後我用它來定義一個Grid.Row的高度:

<UserControl x:Class="GUI.ListViewLayout" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:GUI" 
     xmlns:conv="clr-namespace:GUI.Converter" 
     mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" 
     Loaded="Window_Loaded"> 
    <UserControl.Resources> 
     <Style x:Key="verticalGridViewColumnHeader" TargetType="GridViewColumnHeader"> 
      <Setter Property="ContentTemplate"> 
       <Setter.Value> 
        <DataTemplate> 
         <TextBlock Text="{Binding}" FontWeight="Bold" 
         VerticalAlignment="Center" TextAlignment="Center" HorizontalAlignment="Center"> 
          <TextBlock.LayoutTransform> 
           <RotateTransform Angle="270" /> 
          </TextBlock.LayoutTransform> 
         </TextBlock> 
        </DataTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
     <conv:HeightSyncConverter x:Key="myConverter" /> 
    </UserControl.Resources> 
    <Grid x:Name="grid"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="150" /> 
      <ColumnDefinition Width="150" /> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition x:Name="fillerRow" Height="{Binding View, ElementName=listView1, Converter={StaticResource myConverter}, ConverterParameter={x:Reference listView2}}" /> 
      <RowDefinition Height="*" /> 
     </Grid.RowDefinitions> 
     <Button x:Name="someControl" Grid.RowSpan="2">Placeholder</Button> 
     <ListView x:Name="listView1" Grid.Row="2"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Header 1" Width="60"/> 
        <GridViewColumn Header="Header 2" Width="60" /> 
       </GridView> 
      </ListView.View> 
     </ListView> 
     <ListView x:Name="listView2" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Long Header 1" 
          HeaderContainerStyle="{StaticResource verticalGridViewColumnHeader}" Width="Auto" /> 
        <GridViewColumn Header="Long Header 2" 
          HeaderContainerStyle="{StaticResource verticalGridViewColumnHeader}" Width="Auto" /> 
       </GridView> 
      </ListView.View> 
     </ListView> 

    </Grid> 
</UserControl> 

的問題是,該轉換器的ListView年代以前叫他們頭部被初始化,所以我在重新評估Binding後臺代碼:

public partial class ListViewLayout : UserControl 
{ 
    public ListViewLayout() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     BindingExpression binding = fillerRow.GetBindingExpression(RowDefinition.HeightProperty); 
     binding.UpdateTarget(); 
    } 
} 

所有的一切,我不認爲這是值得的努力和最好的方法是自己定義標題的高度,而不是檢索自動計算的ActualHeight