首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何设置DataGridColumn的宽度以适应内容(“自动”),但完全填充DataGrid在MVVM中的可用空间?

如何设置DataGridColumn的宽度以适应内容(“自动”),但完全填充DataGrid在MVVM中的可用空间?
EN

Stack Overflow用户
提问于 2011-02-14 21:40:58
回答 6查看 78.7K关注 0票数 28

我有一个包含一些数据的WPF DataGrid。我希望设置列的宽度,使内容符合并永远不会被裁剪(相反,水平滚动条应该变得可见)。此外,我希望DataGrid能够填满整个可用位置(我正在使用DockPanel)。我使用以下代码(简化):

代码语言:javascript
复制
<DataGrid ItemsSource="{Binding Table}">
    <DataGrid.Columns>
        <DataGridTextColumn MinWidth="100" Width="Auto" Header="Column 1" Binding="{Binding Property1}" />
        <DataGridTextColumn MinWidth="200" Width="Auto" Header="Column 2" Binding="{Binding Property2}" />
    </DataGrid.Columns>
</DataGrid>

显然,这在Width="Auto"中是行不通的,因为它总是这样的:

这看起来很难看。我希望选择整个行,或者更好的是填充整个宽度的列,但正如人们所看到的,这是行不通的。

如果我使用Width="*",就会裁剪列的内容,这对我来说更糟了。

我找到了一个similar question here,并在那里发布了一个解决方案。这可能有效,但我使用的是MVVM模式,因此ItemsSource在ViewModel中得到更新,我无法从那里考虑一种方法,因为我无法访问DataGridColumnActualWidth属性。而且,如果可能的话,我只想在XAML中这样做。

我很感谢你的帮助。谢谢!

编辑:由于我仍然不知道该怎么做,所以我开始了一笔小小的赏金。如果有人能对我的问题做些什么,我会很高兴的。再次感谢!

编辑2:在索斯的回答之后,我又考虑了一下选项。问题是我需要在应用程序运行期间更新WidthMinWidth属性,所以不仅仅是在加载窗口之后。我已经试过这样做了

代码语言:javascript
复制
column.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
column.MinWidth = column.ActualWidth;
column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);

在某些情况下,当ItemsSource的基础DataGrid正在更新时触发。但是,这不起作用,因为在设置ActualWidth上的Width之后,Auto属性似乎不会改变。是否有选项以某种方式“重新绘制”它,以便更新ActualWidth属性?谢谢!

EN

回答 6

Stack Overflow用户

发布于 2011-02-18 01:10:41

我建议使用你链接到的解决方法。确实有用。在视图的编解码器中,在InitializeComponent()之后向构造函数添加以下内容:

代码语言:javascript
复制
Griddy.Loaded += SetMinWidths; // I named my datagrid Griddy

并将SetMinWidths定义为:

代码语言:javascript
复制
public void SetMinWidths(object source, EventArgs e )
        {
            foreach (var column in Griddy.Columns)
            {
                column.MinWidth = column.ActualWidth;
                column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
            }
        }

我假设您不想使用此解决方案的原因是您认为MVVM禁止代码隐藏中的代码。但由于这完全是一种特定的逻辑,我认为在这种情况下,这是有道理的。整个"MVVM禁止代码背后的代码“的事情有点误解。

但是,如果您受样式指南的约束,或者希望应用程序中的所有数据集都可以使用此逻辑,则可以进行附加行为,这样做的工作如下:

代码语言:javascript
复制
public class SetMinWidthToAutoAttachedBehaviour 
    {
        public static bool GetSetMinWidthToAuto(DependencyObject obj)
        {
            return (bool)obj.GetValue(SetMinWidthToAutoProperty);
        }

        public static void SetSetMinWidthToAuto(DependencyObject obj, bool value)
        {
            obj.SetValue(SetMinWidthToAutoProperty, value);
        }

        // Using a DependencyProperty as the backing store for SetMinWidthToAuto.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SetMinWidthToAutoProperty =
            DependencyProperty.RegisterAttached("SetMinWidthToAuto", typeof(bool), typeof(SetMinWidthToAutoAttachedBehaviour), new UIPropertyMetadata(false, WireUpLoadedEvent));

        public static void WireUpLoadedEvent(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var grid = (DataGrid)d;

            var doIt = (bool)e.NewValue;

            if (doIt)
            {
                grid.Loaded += SetMinWidths;
            }
        }

        public static void SetMinWidths(object source, EventArgs e)
        {
            var grid = (DataGrid)source;

            foreach (var column in grid.Columns)
            {
                column.MinWidth = column.ActualWidth;
                column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
            }
        }
    }

然后,对于要应用此行为的任何数据集,请添加以下内容:

代码语言:javascript
复制
<DataGrid ItemsSource="{Binding Table}" local:SetMinWidthToAutoAttachedBehaviour.SetMinWidthToAuto="true">

然后你的良心,以及你的暗号,都将是清晰的。

票数 34
EN

Stack Overflow用户

发布于 2011-02-14 23:00:40

在模板列中使用文本包装的TextBlock:

代码语言:javascript
复制
<DataGrid ItemsSource="{Binding Table}">      
    <DataGrid.Columns>          
        <DataGridTextColumn MinWidth="100" Width="Auto" Header="Column 1"
                            Binding="{Binding Property1}" />          
        <DataGridTemplateColumn Width="*" Header="Column 2">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Property2}" TextWrapping="Wrap" />  
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>  
</DataGrid>
票数 4
EN

Stack Overflow用户

发布于 2011-02-17 09:28:19

这个怎么样:

对于您的列的MinWidth,您设置了一个绑定到dataGrid的ScrollContent的宽度,并使用一个转换器将此宽度除以列数

您需要为转换器后面的代码,但这将保持您的MVVM结构完整。

可能是一个很长的机会,但没有时间去尝试。

编辑:,我把更多的想法放在这个和那里,一个pb:如果你有一个很大的专栏和几个小的专栏,它将不能很好的工作。我认为所有的科尔都是相同的宽度,这显然不是这样的。

不过,你可能会想用这种方式探索。用转换器在宽度上使用绑定是我能想到的唯一可行的方法:因为在计算列的宽度时基本上需要考虑两个条件,所以没有简单的方法可以做到这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4997596

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档