WPF DataGrid AutoSize问题

时间:2010-11-02 16:50:15

标签: c# wpf datagrid

我最近一直试图在WPF(C / 4.0)DataGrid中进行文本换行,无论我实现哪种解决方案(所有在包装模板中都使用某种形式的TextBlock),它会混淆自动高度网格并在网格底部产生过多的空白区域(为了可见性而设置为黄色)。

我的代码:(注释代码是文本换行的替代解决方案,但仍会导致空间过大)

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <DataGrid Grid.Row="0" AutoGenerateColumns="False" ColumnWidth="*" Name="dgFamilyHistories" IsReadOnly="True" 
                          HorizontalScrollBarVisibility="Disabled" 
                      ItemsSource="{Binding Path=Patient.FamilyHistories}" RowDetailsVisibilityMode="Visible"
                      GridLinesVisibility="All">
        <DataGrid.Resources>
            <Style TargetType="{x:Type DataGridRow}">
                <Setter Property="Height" Value="Auto"/>
            </Style>
            <!--<Style TargetType="{x:Type DataGridCell}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type DataGridCell}">
                            <Border Name="border">
                                <ContentControl Content="{TemplateBinding Content}">
                                    <ContentControl.ContentTemplate>
                                        <DataTemplate>
                                            <DockPanel>
                                                <TextBlock TextWrapping="WrapWithOverflow" TextTrimming="CharacterEllipsis"  
                                                         Width="Auto" Height="Auto" Text="{Binding Text}"/>
                                            </DockPanel>
                                        </DataTemplate>
                                    </ContentControl.ContentTemplate>
                                </ContentControl>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>-->
        </DataGrid.Resources>
        <DataGrid.Background>
            <SolidColorBrush Color="Yellow" />
        </DataGrid.Background>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Date" Binding="{Binding DateEntered, StringFormat={}{0:dd/MM/yyyy}}" Width="85"/>
            <!--<DataGridTextColumn Header="Relation" Binding="{Binding Relation}"/>-->
            <DataGridTemplateColumn Header="Relation">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock TextTrimming="CharacterEllipsis" TextWrapping="Wrap" Text="{Binding Path=Relation}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
            <!--<DataGridTextColumn Header="Illness" Binding="{Binding Illness}"/>-->
            <DataGridTemplateColumn Header="Illness">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock TextTrimming="CharacterEllipsis" TextWrapping="Wrap" Text="{Binding Path=Illness}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
            <!--<DataGridTextColumn Header="Health" Binding="{Binding Health}"/>-->
            <DataGridTemplateColumn Header="Health">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock TextTrimming="CharacterEllipsis" TextWrapping="Wrap" Text="{Binding Path=Health}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
            <DataGridTextColumn Header="Birth Date" Binding="{Binding DateOfBirth, StringFormat={}{0:dd/MM/yyyy}}" Width="85"/>
            <DataGridTextColumn Header="Death Date" Binding="{Binding DateOfDeath, StringFormat={}{0:dd/MM/yyyy}}" Width="85"/>
            <!--<DataGridTextColumn Header="Death Cause" Binding="{Binding CauseOfDeath}"/>-->
            <DataGridTemplateColumn Header="Death Cause">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock TextTrimming="CharacterEllipsis" TextWrapping="Wrap" Text="{Binding Path=CauseOfDeath}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
            <DataGridTextColumn Header="Age" Binding="{Binding Age}" Width="50"/>
        </DataGrid.Columns>
        <DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <Label Name="lblDetails" Content="{Binding Path=Comments}" ContentStringFormat="{}Comments: {0}" Margin="15,0,0,0"/>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding Path=Comments, Converter={Converters:IsNullStringConverter}}" Value="True">
                        <Setter TargetName="lblDetails" Property="Visibility" Value="Collapsed"/>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </DataGrid.RowDetailsTemplate>
    </DataGrid>
    <DockPanel Grid.Row="1" Background="Blue">

    </DockPanel>
</Grid>

2 个答案:

答案 0 :(得分:1)

Use this way, to expand your datagrid with proper height and width
   <my:DataGridTemplateColumn Header="{DynamicResource name}"  Width="*" 
                                                           CanUserSort="True" SortMemberPath="Name"
                                                           HeaderStyle="{StaticResource StaffDgColoumnHeaderStyle}">
                                <my:DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Style="{StaticResource RowTextblockStyle}" >`enter code here`
                                                <Hyperlink>
                                                    <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Name}"
                                                               TextWrapping="NoWrap" TextTrimming="CharacterEllipsis"/>
                                                </Hyperlink>
                                            </TextBlock>
                                    </DataTemplate>
                                </my:DataGridTemplateColumn.CellTemplate>
                            </my:DataGridTemplateColumn>

                            <my:DataGridTemplateColumn Header="{DynamicResource sft}"  Width="*" 
                                                           CanUserSort="True" SortMemberPath="ShiftName"
                                                           HeaderStyle="{StaticResource StaffDgColoumnHeaderStyle}">
                                <my:DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding ShiftName}" ToolTip="{Binding ShiftName}"
                                                       Style="{StaticResource RowTextblockStyle}"/>
                                    </DataTemplate>
                                </my:DataGridTemplateColumn.CellTemplate>
                            </my:DataGridTemplateColumn>

See Width ="*" Or Use Width ="Auto" or Width = "20*" as per as your requirement.

答案 1 :(得分:0)

是的,我也遇到过,一定是个bug。问题实际上不是包装本身,而是一旦单元格变得比它小,那么DataGrid的高度将不会更新,直到它因任何原因调整大小(改变Window的大小或其他)。我没有一个很好的解决方案,但这里有一些解决方法。

更新

优化版本,使用DataGridColumn而不是TextBlocks。使用附加属性WrapColumn(默认为false)来了解包装的列。

的Xaml。为每个包装列添加local:MainWindow.WrapColumn =“True”。

<DataGridTemplateColumn Header="Health"
                        local:MainWindow.WrapColumn="True">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock TextTrimming="CharacterEllipsis"
                       TextWrapping="Wrap"
                       Text="{Binding Path=Health}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

添加附加属性

public partial class MainWindow : Window
{
    private static readonly DependencyProperty WrapColumnProperty =
          DependencyProperty.RegisterAttached("WrapColumn",
                                              typeof(bool),
                                              typeof(MainWindow));
    public static void SetWrapColumn(DependencyObject element, bool value)
    {
        element.SetValue(WrapColumnProperty, value);
    }
    public static bool GetWrapColumn(DependencyObject element)
    {
        return (bool)element.GetValue(WrapColumnProperty);
    }

为WrapColumn设置为true的每个DataGridColumn添加一个ActualWidth更改的侦听器

public MainWindow()
{
    InitializeComponent();

    DependencyPropertyDescriptor dependencyPropertyDescriptor =
        DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn));

    if (dependencyPropertyDescriptor != null)
    {
        foreach (DataGridColumn column in c_dataGrid.Columns)
        {
            if (GetWrapColumn(column) == true)
            {
                dependencyPropertyDescriptor.AddValueChanged(column, DataGridColumn_ActualWidthChanged);
            }
        }
    }

    void DataGridColumn_ActualWidthChanged(object sender, EventArgs e)
    {
        c_dataGrid.Width = c_dataGrid.ActualWidth - 1;
        EventHandler eventHandler = null;
        eventHandler = new EventHandler(delegate
        {
            c_dataGrid.Width = double.NaN;
            c_dataGrid.LayoutUpdated -= eventHandler;
        });
        c_dataGrid.LayoutUpdated += eventHandler;
    }
    //...
}