【问题标题】:WPF DataGrid AutoSize IssueWPF DataGrid AutoSize 问题
【发布时间】:2011-05-04 01:29:57
【问题描述】:

我最近一直在尝试让文本换行在 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>

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    是的,我也遇到过,一定是bug。问题实际上不在于 Wrapping 本身,而在于一旦单元格变得比原来更小,那么 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;
        }
        //...
    }
    

    【讨论】:

    • 此解决方案有效,但在使用流文档打印时,自动尺寸仍然会混淆。如果流文档触发调整大小,则其高度显示正确,但所有列都被压扁。
    • 看到你批准和不批准它一段时间后,所以我认为有些东西不是在玩球。所以列最终宽度最小,或者有什么影响?
    • 差不多,基本上我将网格放入流文档中,然后打印。基本上发生的事情是,一旦流文档超过一页,它上面的第一个数据网格就会被弄乱。 (整体网格的宽度正确,标题也是如此,但脚趾单元格都向左挤压。我会尝试发布屏幕截图。
    • 对不起,让我修改一下,网格的宽度是正确的,但标题和单元格向左挤压(可能是最小宽度)
    【解决方案2】:
    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.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 1970-01-01
      • 2013-05-12
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多