简体   繁体   English

WPF 数据网格 MinWidth=auto MaxWidth=*

[英]WPF datagrid MinWidth=auto MaxWidth=*

I have a seemingly simple use case but its been troubling me for hours我有一个看似简单的用例,但它困扰了我几个小时

I have a grid with two rows and two columns, the first column should take all the available width and the second column should take the width it requires.我有一个两行两列的网格,第一列应该采用所有可用的宽度,第二列应该采用它需要的宽度。 The problem is with the 'required width' of the second column.问题在于第二列的“所需宽度”。 This column contains a datagrid in the top row and a label (for simplicity) in the bottom row.此列在顶行包含一个数据网格,在底行包含一个标签(为简单起见)。 The datagrid has two columns which should both take up 50% width of the datagrid.数据网格有两列,它们都应占据数据网格宽度的 50%。

I want:我想要:

  • If the label is wider than the datagrid the datagrid should scale up (and NO semi column MAY appear at the end of the datagrid filling up the remaining space)如果标签比数据网格宽,则数据网格应按比例放大(并且在填充剩余空间的数据网格末尾可能不会出现半列)
  • If the datagrid is wider than the label, the column may not be smaller than the required size for the datagrid.如果数据网格比标签宽,则该列不得小于数据网格所需的大小。

The problem:问题:

  • If I set the datagrid columns to take all available space (width='*') it works if the label is bigger than the datagrid (but if the label is smaller the datagrid shrinks to the width of the label, and not al text is readable)如果我将 datagrid 列设置为占用所有可用空间 (width='*'),则如果标签大于 datagrid(但如果标签较小,则 datagrid 会缩小到标签的宽度,而不是 al 文本)可读)
  • If I set the columns to 'autosize' it works is the label is smaller than the datagrid (but if the label is bigger the 'semi' column appears (and it really hurts my eyes)).如果我将列设置为“自动调整大小”,它的工作原理是标签小于数据网格(但如果标签更大,则会出现“半”列(这真的伤害了我的眼睛))。

The code:编码:

x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="200" Width="400">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="auto"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
    </Grid.RowDefinitions>
    <Grid Grid.Column="1" Name="grid">
        <!-- Change column width to simulate the problemn-->
        <DataGrid ItemsSource="{Binding Items}" ColumnWidth="*" RowHeaderWidth="0" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}"/>
    </Grid>
    <!-- change label text to simulate problemn-->
    <Label Grid.Row="1" Grid.Column="1" Content="x"/>
</Grid>

  • The binding to the actual width of the grid is to have the columns scale up correctly与网格实际宽度的绑定是使列正确放大
  • The Items is a List of objects (which contain two string values) Items 是一个对象列表(包含两个字符串值)

This is dirty and would probably cause me to rethink my design, but it works based on your requirements.这很脏,可能会让我重新考虑我的设计,但它可以根据您的要求工作。 I'm not sure how else to achieve this without creating a custom control or greatly modifying the DataGrid default template, but here goes.我不知道如何在不创建自定义控件或大量修改DataGrid默认模板的情况下实现这一点,但这里是。

Change your DataGrid styling to this and give names to both the Label and the DataGrid .将您的DataGrid样式更改为此,并为LabelDataGrid命名。

<DataGrid Name="dg" ItemsSource="{Binding Items}" CanUserResizeColumns="False"/>
///
<Label Grid.Row="1" Grid.Column="1" Content="x" Name="label"/>

Then create a ContentRendered event for your MainWindow .然后为您的MainWindow创建一个ContentRendered事件。

 Title="MainWindow" Height="450" Width="800" Name="mw" ContentRendered="Mw_ContentRendered">

Now in the render event, manually resize columns after the render occurs.现在在渲染事件中,在渲染发生后手动调整列的大小。 You can't assign a star to the width as it won't resize correctly, so you need to divide your widths evenly base on column count.您不能为宽度分配星号,因为它不会正确调整大小,因此您需要根据列数均匀划分宽度。

private void Mw_ContentRendered(object sender, EventArgs e)
{    
     //Loop through columns and resize
     for (int x = 0; x < dg.Columns.Count; x++)
     {
         double div = dg.ActualWidth / dg.Columns.Count;
         double add = div - dg.Columns[x].ActualWidth;
         if (add < 0) { div += -add; }
         dg.Columns[x].Width = new DataGridLength(div);         
     }     
}

EDIT: Updated width logic to account for uneven widths编辑:更新宽度逻辑以解决不均匀的宽度

I ended up creating my own user control.我最终创建了自己的用户控件。

This was relatively easy as I know at design time which rows I will have in the 'datagridview'.这相对容易,因为我在设计时就知道我将在“datagridview”中包含哪些行。

Tronald's suggestion works, provided that the data does not change after rendering (mine does, both the datagrid contents and the 'label' change based on selections made in the rest of the application). Tronald 的建议有效,前提是数据在呈现后不会更改(我的建议是这样,数据网格内容和“标签”都根据在应用程序其余部分中所做的选择而更改)。

I still think that the 'Width="*" MinWidth="auto"' combination should be possible for a datagrid so If anybody has a solution.我仍然认为 'Width="*" MinWidth="auto"' 组合应该适用于数据网格,所以如果有人有解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM