如何设置DataGridColumn的宽度以适应内容(“Auto”),但是完全填充MVVM中DataGrid的可用空间? [英] How can I set the width of a DataGridColumn to fit contents ("Auto"), but completely fill the available space for the DataGrid in MVVM?

查看:233
本文介绍了如何设置DataGridColumn的宽度以适应内容(“Auto”),但是完全填充MVVM中DataGrid的可用空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含一些数据的WPF DataGrid 我想设置列的宽度,使内容适合,从不被裁剪(相反,水平滚动条应该可见)。此外,我想要 DataGrid 填充整个可用空间(我正在使用一个 DockPanel )。我使用以下代码(简化):

I have a WPF DataGrid that contains some data. I would like to set the width of the columns such that the content fits in and never gets cropped (instead, a horizontal scroll bar should become visible). Additionally, I want the DataGrid to fill the whole place available (I am working with a DockPanel). I am using the following code (simplified):

<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 ,因为它总是看起来像这样:

This apparently does not work out of the box with Width="Auto" as it always looks something like this:

这显然看起来很丑陋。我想要选择整行,或者更好的是填充整个列的列,但是可以看到,这不行。

This obviously looks ugly. I would like to have the whole row selected, or, which would be much better, the columns to fill the whole width, but as one can see, this does not work.

如果我使用 Width =*,则列的内容会被裁剪,对我来说更糟糕。

If I use Width="*" instead, the content of the columns gets cropped which is even worse for me.

我在这里找到了一个类似的问题a>,并发布了一个解决方法。这可能会起作用,但是我正在使用MVVM模式,所以 ItemsSource在ViewModel 中被更新,我无法想到从那里做一个方法,因为我无法访问 ActualWidth 属性的 DataGridColumn 。此外,我想只在XAML中做到这一点,如果可能的话。

I found a similar question here, and a workaround was posted there. This may work, but I am working with the MVVM pattern, so the ItemsSource gets updated in the ViewModel and I cannot think about a way of doing it from there, because I cannot access the ActualWidth property of the DataGridColumn. Also, I would like to do it only in XAML if possible.

我会感谢任何帮助。谢谢!

I would appreciate any help. Thanks!

编辑:由于我还没有一个线索,该怎么做,我开始一个小小的赏金。对于有关我的问题的建议,我会很高兴。再次感谢!

As I still don't have a clue what to do about it, I start a small bounty. I would be very happy about a suggestion what one could do about my problem. Thanks again!

编辑2:在saus'回答后,我再次考虑了选项。问题是,在应用程序运行期间,我还需要更新 Width MinWidth 属性,因此不仅加载窗口后。我已经尝试过像

Edit 2: After saus' answer I thought about the options again. The problem is that I need to update the Width and the MinWidth properties also during the application is running, so not only after loading the window. I already tried to do something like

column.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
column.MinWidth = column.ActualWidth;
column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);



< DataGrid 的c>正在更新。但是,这不起作用,因为 ActualWidth 属性似乎在<$ c $宽度之后设置自动。有没有什么选择以某种方式重新绘制,以便更新$ code> ActualWidth 属性?谢谢!

in some event that is fired when the underlying ItemsSource of the DataGrid is updating. However, this does not work, as the ActualWidth property does not seem to change after setting the Width on Auto. Is there an option to somehow "repaint" it in order to get the ActualWidth property updated? Thanks!

推荐答案

我建议使用您链接的解决方法。它工作正常在您的视图的代码中,将以下内容添加到InitializeComponent()之后的构造函数中:

I would suggest using the workaround that you linked to. It does work. In the codebehind of your view, add the following to the constructor after InitializeComponent():

Griddy.Loaded += SetMinWidths; // I named my datagrid Griddy

并将SetMinWidths定义为:

and define SetMinWidths as:

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禁止codebehind中的代码的东西有点误解。

I'm assuming that the reason you don't want to use this solution is that you believe that MVVM prohibits code in the codebehind. But since this is entirely view specific logic I believe that it is justified in this case. The whole "MVVM prohibits code in the codebehind" thing is a bit of a misconception.

但是,如果您受到样式指南的约束,或者您希望此逻辑可用于应用程序中的所有数据标签,则可以使附件行为这个:

But if you are bound by style guides, or you want this logic to be available for all datagrids in your app, you can make an attached behaviour that does the job like this:

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);
            }
        }
    }

然后对于任何datagrid您要应用此行为,添加以下内容:

and then for any datagrid that you want to apply this behaviour to, add the following:

<DataGrid ItemsSource="{Binding Table}" local:SetMinWidthToAutoAttachedBehaviour.SetMinWidthToAuto="true">

然后,你的良心以及你的代码将被清除。

And then your conscience, as well as your codebehind, will be clear.

这篇关于如何设置DataGridColumn的宽度以适应内容(“Auto”),但是完全填充MVVM中DataGrid的可用空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆