2010-11-18 61 views
11

假設我有一個這樣定義的DataGrid RowDetails寬度問題

<DataGrid AreRowDetailsFrozen="True" 
      ItemsSource="{Binding MyCollection}" 
      AutoGenerateColumns="False"> 
    <DataGrid.RowDetailsTemplate> 
     <DataTemplate> 
      <Border CornerRadius="5" BorderBrush="Red" 
        BorderThickness="2" Background="Black"> 
       <TextBlock Foreground="White" Text="{Binding RowDetails}" 
          TextWrapping="Wrap"/> 
      </Border> 
     </DataTemplate> 
    </DataGrid.RowDetailsTemplate> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="0" Binding="{Binding Value1}"/> 
     <DataGridTextColumn Header="1" Binding="{Binding Value2}"/> 
     <DataGridTextColumn Header="2" Binding="{Binding Value3}"/> 
     <DataGridTextColumn Header="3" Binding="{Binding Value4}"/> 
    </DataGrid.Columns> 
</DataGrid> 

,看起來像這樣與不RowDetails

alt text

在圖片中,我得到一個正確的一個DataGrid非常長的DataGridRow永不換行。
是否有可能使RowDetails使用與DataGrid相同的寬度而不影響寬度本身?

事情我都試過,實現了包裝,但沒有一個令人滿意的方式

    在邊境或TextBlock的
  • 集合寬度或MaxWidth。不是很有活力。
  • 在DataGrid上設置ScrollViewer.Horizo​​ntalScrollBarVisibility =「Disabled」。柱子不合適時不太好。

回答

10

這就是我最終做的。我寧願在DataGrid上使用Property,但由於不存在這樣的屬性,所以我需要一個解決方法。

alt text

首先,我只是用ActualWidth的從父DataGrid和去除恆定的9.這個工作在第一,但在垂直滾動條變爲可見的失敗,所以我不得不使用一個MultiBinding。

<DataGrid.RowDetailsTemplate> 
    <DataTemplate> 
     <Border HorizontalAlignment="Left" CornerRadius="5" 
       BorderBrush="Red" BorderThickness="2" Background="Black"> 
      <Border.Width> 
       <MultiBinding Converter="{StaticResource RowDetailsWidthMultiConverter}" 
           ConverterParameter="9"> 
        <Binding RelativeSource="{RelativeSource AncestorType={x:Type DataGrid}}" 
          Path="ActualWidth"/> 
        <Binding RelativeSource="{RelativeSource AncestorType={x:Type ScrollViewer}}" 
          Path="ComputedVerticalScrollBarVisibility"/> 
       </MultiBinding> 
      </Border.Width> 
      <TextBlock Foreground="White" Text="{Binding RowDetails}" TextWrapping="Wrap"/> 
     </Border> 
    </DataTemplate> 
</DataGrid.RowDetailsTemplate> 

而在轉換器中,我用另一個常量(16)來補償可見的垂直滾動條(如果它是可見的)。

public class RowDetailsWidthMultiConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     double originalWidth = (double)values[0]; 
     Visibility verticalScrollbarVisibility = (Visibility)values[1]; 
     double subtractWidth = System.Convert.ToDouble(parameter); 
     double returnWidth = originalWidth - subtractWidth; 
     if (verticalScrollbarVisibility == Visibility.Visible) 
     { 
      return returnWidth - 16; 
     } 
     return returnWidth; 
    } 
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return null; 
    } 
} 

更新

我的溶液一點改進,採用ActualWidth的用於ItemsPresenter而不是數據網格,從而去除(其中ActualWidth的不依賴於可見滾動條改變)需要一個MultiConverter和兩個常量。

<DataGrid.Resources> 
    <local:SubtractConstantConverter x:Key="SubtractConstantConverter"/> 
</DataGrid.Resources> 
<DataGrid.RowDetailsTemplate> 
    <DataTemplate> 
     <Border HorizontalAlignment="Left" CornerRadius="5" 
       BorderBrush="Red" BorderThickness="2" Background="Black" 
       Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsPresenter}}, 
           Path=ActualWidth, 
           Converter={StaticResource SubtractConstantConverter}, 
           ConverterParameter=6}"> 
      <TextBlock Foreground="White" Text="{Binding RowDetails}" TextWrapping="Wrap"/> 
     </Border> 
    </DataTemplate> 
</DataGrid.RowDetailsTemplate> 

SubtractConstantConverter

public class SubtractConstantConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     double originalValue = (double)value; 
     double subtractValue = System.Convert.ToDouble(parameter); 
     return originalValue - subtractValue; 
    } 
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return null; 
    } 
} 
+0

與您的更新版本與ItemsPresenter作爲祖先垂直滾動條不尊重。我減去22來避免水平滾動條。 – user2452157 2016-06-29 16:24:18

2

您可能能夠將MaxWidth綁定到ElementName=PART_ColumnHeadersPresenter, Path=ActualWidth或者RenderSize.Width。我相信這是DataGrid模板的一部分,它顯示列,理論上它應該可以工作

+0

感謝您的提示!這與我最終做的事情非常接近。 – 2010-11-18 15:08:46

2

感謝Meleak,您的解決方案的工作很適合我。我們WPF新手的一個小增加。務必將您的Converter類聲明爲資源,以便在Binding表達式中引用它。

我把它放在App裏。XAML是這樣的:

<Application x:Class="ISCBilling.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:conv="clr-namespace:my.application.namespace" 
      StartupUri="IscBillingWindow.xaml"> 
    <Application.Resources> 

     <conv:RowDetailsWidthMultiConverter x:Key="RowDetailsWidthMultiConverter" /> 

    </Application.Resources> 
</Application> 
+0

感謝您的回覆,我將其添加到了我更新的解決方案中,該解決方案不再需要MultiConverter。 – 2011-01-01 21:23:20

1

爲了節省其他人有些撓頭,試錯時間:

與弗雷德裏克Hedblad最近(1/1/11)solution大驚小怪了一段時間我想通後那麼轉換器參數值應該是6 + [左邊距} + [右邊距](即模板中最外層容器的邊距)。在檢查屏幕截圖的放大後,我預計每行左側豎條的寬度。

+0

該解決方案是否可以針對不同的DPI設置進行縮放! – Ahmad 2015-05-18 07:54:03

13

在這裏的答案感覺像一個解決方法,所以我做了一些研究,並找到Telerik論壇上的解決方案,因爲我們使用他們的RadGridView。原來這個解決方案也適用於DataGrid。

關鍵是將ScrollViewer.Horizo​​ntalScrollBarVisibility屬性設置爲Disabled,請參閱下面的示例。

<DataGrid ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 
<DataGrid.RowDetailsTemplate> 
    <DataTemplate> 
     <Border> 
      <TextBlock Foreground="White" Text="{Binding RowDetails}" 
         TextWrapping="Wrap"/> 
     </Border> 
    </DataTemplate> 
</DataGrid.RowDetailsTemplate> 

編輯: 一個副作用是,如果列水平需要更多的空間比有房,他們將被裁剪。所以如果這是一個問題,那麼這個解決方案不是最優的。

+0

工程就像一個魅力!非常感謝,我不會自己想出來...... – Ash 2013-04-25 12:04:30

+0

當您實際需要水平ScrolBar以滾動到隱藏列時,此解決方案不會縮放! – Ahmad 2015-05-18 08:00:27

2

這就是我最終所做的:將行細節寬度綁定到其演示者的實際寬度,然後添加具有變化厚度的邊框以補償演示者中存在/不存在垂直滾動條。這種方法對我來說非常合適。 xaml示例:

<DataGrid.RowDetailsTemplate> 
    <DataTemplate> 
     <Border BorderThickness="2,2,8,2" 
       Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsPresenter}}, Path=ActualWidth}" 
       HorizontalAlignment="Left" > 
      <!-- add the row details view contents here --> 
     </Border> 
    </DataTemplate> 
</DataGrid.RowDetailsTemplate>