2015-04-22 28 views
1

假设我有6个属性的对象:相对列宽不工作时数据网格是嵌套在分组数据网格

public class MyClass 
{ 
    public string Attribute1 { get; set; } 
    public string Attribute2 { get; set; } 
    public string Attribute3 { get; set; } 
    public string Attribute4 { get; set; } 
    public string Attribute5 { get; set; } 
    public string Attribute6 { get; set; } 
} 

我在数据网格中显示这些对象的集合:

<Grid> 
    <DataGrid x:Name="myGrid" Margin="5, 5, 5, 5" AutoGenerateColumns="False" CanUserAddRows="False" IsReadOnly="True"> 
     <DataGrid.GroupStyle> 
      <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}"> 
       <GroupStyle.Panel> 
        <ItemsPanelTemplate> 
         <DataGridRowsPresenter/> 
        </ItemsPanelTemplate> 
       </GroupStyle.Panel> 
      </GroupStyle> 
     </DataGrid.GroupStyle> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="Attribute1" Binding="{Binding Attribute1}" Width="5*"/> 
      <DataGridTextColumn Header="Attribute2" Binding="{Binding Attribute2}" Width="5*"/> 
      <DataGridTextColumn Header="Attribute3" Binding="{Binding Attribute3}" Width="10*"/> 
     </DataGrid.Columns> 
    </DataGrid> 
</Grid> 

我这样填充我的网格,按“属性1”分组...

public MainWindow() 
    { 
     InitializeComponent(); 

     ObservableCollection<MyClass> data = new ObservableCollection<MyClass>(); 
     data.Add(new MyClass { Attribute1 = "Red", Attribute4 = "Circle", Attribute5 = "Large", Attribute6 = "Transparent" }); 
     data.Add(new MyClass { Attribute1 = "Red", Attribute4 = "Square", Attribute5 = "Medium", Attribute6 = "Opaque" }); 
     data.Add(new MyClass { Attribute1 = "Red", Attribute4 = "Triangle", Attribute5 = "Large", Attribute6 = "Opaque" }); 
     data.Add(new MyClass { Attribute1 = "Yellow", Attribute4 = "Square", Attribute5 = "Large", Attribute6 = "Transparent" }); 
     data.Add(new MyClass { Attribute1 = "Blue", Attribute4 = "Triangle", Attribute5 = "Small", Attribute6 = "Transparent" }); 
     data.Add(new MyClass { Attribute1 = "Blue", Attribute4 = "Sphere", Attribute5 = "Small", Attribute6 = "Opaque" }); 


     ListCollectionView lcv = new ListCollectionView(data); 
     lcv.GroupDescriptions.Add(new PropertyGroupDescription("Attribute1")); 
     myGrid.ItemsSource = lcv; 

    } 

我给我的GroupItems样式显示膨胀中的嵌套的DataGrid:

<Window.Resources> 
    <Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type GroupItem}"> 
        <Expander x:Name="exp" IsExpanded="True" Foreground="Black"> 
         <Expander.Header> 
           <TextBlock Foreground="Black" Text="{Binding Name}"/> 
         </Expander.Header> 
         <DockPanel> 
          <DataGrid ItemsSource="{Binding Items}" x:Name="subGrid" AutoGenerateColumns="False" IsReadOnly="True" CanUserAddRows="False"> 
           <DataGrid.Columns> 
            <DataGridTextColumn Header="Attribute 4" Binding="{Binding Attribute4}" Width="Auto"/> 
            <DataGridTextColumn Header="Attribute 5" Binding="{Binding Attribute5}" Width="Auto"/> 
            <DataGridTextColumn Header="Attribute 6" Binding="{Binding Attribute6}" Width="Auto"/> 
           </DataGrid.Columns> 
          </DataGrid> 
         </DockPanel> 
        </Expander> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 

设置为“自动”我的嵌套的DataGrid列宽......它的伟大工程:

enter image description here

问题是,当我尝试使用相对宽度...

<DataGrid ItemsSource="{Binding Items}" x:Name="subGrid" AutoGenerateColumns="False" IsReadOnly="True" CanUserAddRows="False"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Attribute 4" Binding="{Binding Attribute4}" Width="1*"/> 
     <DataGridTextColumn Header="Attribute 5" Binding="{Binding Attribute5}" Width="1*"/> 
     <DataGridTextColumn Header="Attribute 6" Binding="{Binding Attribute6}" Width="2*"/> 
    </DataGrid.Columns> 
</DataGrid> 

现在它看起来像这样... enter image description here

不仅列超级瘦......它们不像以往那样用鼠标调整大小。

这个问题真的让我感到困惑。我已经搜索过,并尝试了几个有点相关的问题,没有任何运气。

如何设置嵌套DataGrid上的列以使用相对宽度?

回答

2

我认为问题在于WPF并不知道DockPanel的宽度是多少,所以你得到了那些瘦小的列。

一种解决方案是将DockPanel(或DataGrid)的宽度设置为500像素的固定宽度。

另一种解决方案是将DataGrid的宽度绑定到DockPanel的ActualWidth。这可以工作,但DataGrid只会增大,当窗口变小时它不会缩小。

<DataGrid ItemsSource="{Binding Items}" 
      x:Name="subGrid" 
      AutoGenerateColumns="False" 
      IsReadOnly="True" 
      CanUserAddRows="False" 
      Width="{Binding 
        RelativeSource={RelativeSource AncestorType=DockPanel}, Path=ActualWidth}"> 

另一种解决方案是将DockPanel的宽度绑定到扩展器的ActualWidth。问题在于它不能正常工作......扩展器变得更大,因为DockPanel变得更大,并且我们进入循环。我们真正想要的是扩展器的ActualWidth减去足以不使扩展器增加其宽度。我已经尝试了一下,“ActualWidth - 3”似乎有效(但是为什么3 ...)。如果添加填充或边距,则可能需要更改此3。为了将其转换为绑定,我们需要一个IValueConverter。

public class ActualWidthConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value is double) 
      return (double)value - 3; 
     return value; 
    } 
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

你需要转换器添加为资源(应用程序或窗口或其他):

<Window .... 
    xmlns:app="clr-namespace:WpfApplication25"> 
<Window.Resources> 
    <app:ActualWidthConverter x:Key="ActualWidthConverter" /> 
</Window.Resources> 

,当然,你需要的绑定应用到的宽度DockPanel:

<DockPanel Width="{Binding RelativeSource={RelativeSource AncestorType=Expander}, Path=ActualWidth, Converter={StaticResource ActualWidthConverter}}"> 

这不是一个完美的解决方案,但它可能会有帮助吗?这种方法的替代版本可以使用MultiBinding;传递Expander的ActualWidth和DockPanel的Margin:ActualWidth - Margin.Left - Margin.Right - 3(我还在想为什么3?并且它会在其他人的计算机上也是3?)。

+0

美丽!这就是我需要的,非常感谢 –