【问题标题】:Resize DataGrid Column OnLoaded programmatically以编程方式调整 DataGrid 列 OnLoaded
【发布时间】:2019-08-09 03:27:26
【问题描述】:

我有这个 DataGrid,当我第一次加载数据时,它看起来像这样:

所以,它几乎是完美的,但是当我将窗口大小调整到最大时,我真正想要的会显示出来 - 现在列的布局如下:

我想在 DataGrid 视图的右侧布置最右侧的列,并让左侧列分配视图的其余部分。

我的问题是:我可以在 DataGrid 上调用一个事件来导致这种列布局,否则只有在窗口最大化时才会发生这种布局?

DataGrid 的 XAML 的简化版本如下所示:

<DataGrid
   ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource TemplatedParent}}"
   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
   ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
   ScrollViewer.VerticalScrollBarVisibility="Auto" 
   ScrollViewer.CanContentScroll="True"
   AutoGenerateColumns="False"
   GridLinesVisibility="None"
   ColumnWidth="*">
   <DataGrid.Columns>
       <DataGridTemplateColumn Width="*" Header="Name">
           <DataGridTemplateColumn.CellTemplate>
               <DataTemplate>
                   <Grid>
                       <Grid.ColumnDefinitions>
                           <ColumnDefinition Width="Auto"/>
                           <ColumnDefinition Width="*"/>
                       </Grid.ColumnDefinitions>

                       <TextBlock Grid.Column="1"
                                  Text="{Binding ItemName}"
                                  ToolTipService.ShowOnDisabled="true"
                                  >
                        </TextBlock>
                   </Grid>
               </DataTemplate>
           </DataGridTemplateColumn.CellTemplate>
       </DataGridTemplateColumn>
       <DataGridTemplateColumn Width="Auto" Header="Size">
           <DataGridTemplateColumn.CellTemplate>
               <DataTemplate>
                   <TextBlock
                       Text="{Binding ItemLengthA}"
                              HorizontalAlignment="Right"
                              Margin="3,0,0,0"
                   />
               </DataTemplate>
           </DataGridTemplateColumn.CellTemplate>
       </DataGridTemplateColumn>
       <DataGridTemplateColumn Width="Auto" Header="Modified">
           <DataGridTemplateColumn.CellTemplate>
               <DataTemplate>
                   <TextBlock
                       Text="{Binding ItemLastUpdateA}"
                       HorizontalAlignment="Right"
                       Margin="3,0,0,0"
                   />
               </DataTemplate>
           </DataGridTemplateColumn.CellTemplate>
       </DataGridTemplateColumn>
   </DataGrid.Columns>
</DataGrid>

我也有工作应用程序/控件来检查here,但我认为查看上面的 XAML 应该足以找到基于给定布局的解决方案。

【问题讨论】:

  • 代码对我来说似乎没问题。我用一些数据测试了一个类似的DataGrid,无论大小如何改变,它都会像你的第二张图片一样继续显示。所以也许其他的东西影响了布局。
  • 您是否将 DataGrid 托管在具有 SizeToContent="WidthAndHeight" 或 SizeToContent="Width" 的窗口内?当窗口适应内容宽度时,我遇到了这种行为。
  • Window 代码只是标准代码,如果你创建一个新的 WPF 项目,你会得到它——那里没有什么特别的东西。还有一些其他的东西,比如滚动同步和 RowStyle 背景颜色自定义,我可以尝试关闭它们以查看行为是否发生变化,但直到现在我认为这并不重要......我会检查关闭这些东西是否会改变 Column宽度行为...

标签: c# wpf datagrid column-width


【解决方案1】:

我试图重现您的情况并得出结果:这取决于您将如何使用 ItemsSource。 如果 ViewModel 中的 ItemsSource 是一个 List,那么您只需为其分配一个新实例,然后调用 PropertyChanged 事件。这将导致列的行为如您所愿(Width="Auto")。

      ItemsSource = new List<Data>();
      // ItemsSource.Add(new Data()); // ..adding data 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ItemsSource)));

但是,由于它目前无法正常工作,我猜您可能有一个 ObservableCollection 作为 ItemsSource,并且您正在那里添加项目。在我的测试中,它的行为与您描述的一样,列保持较小,除非手动调整窗口或列的大小。

  public ObservableCollection<Data> ItemsSource { get; set; }
  public void AddItems()
  {
      ItemsSource.Add(new Data()); // not working
  }

我发现强制网格执行此操作的唯一方法是将列宽从自动取消设置为某个值,然后再返回。使用按钮来执行此操作。但任何 Onload 也可以工作

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        foreach (DataGridTemplateColumn item in MyDataGrid.Columns)
        {
            if (item.Width.IsAuto)
            {
                item.Width = new DataGridLength(item.ActualWidth, item.Width.UnitType);
                item.Width = DataGridLength.Auto;
            }
        }
    }

【讨论】:

  • 我可以验证您的发现 - 我也可以使用 ObservableCollection 重现相同的所需行为 - 看起来它不是集合的类型,而是现有集合确实被新集合替换的事实集合后跟一个 PropertyChanged 事件,使这项工作。 ObservableCollection 实际上发送了一个 NotifyCollectionChangedAction.Reset ,但这似乎不足以让 Grid 真正正确地布置项目。因此,现在的解决方案是在每次重新加载时始终重建整个(可观察的)集合......感谢您的提示:-)
猜你喜欢
  • 2012-01-29
  • 2016-06-17
  • 2012-03-14
  • 1970-01-01
  • 1970-01-01
  • 2016-09-30
  • 2018-07-13
  • 2013-01-09
  • 1970-01-01
相关资源
最近更新 更多