gpt4 book ai didi

c# - 如何设置 DataGridColumn 的宽度以适应内容 ("Auto"),但完全填充 MVVM 中 DataGrid 的可用空间?

转载 作者:IT王子 更新时间:2023-10-29 04:30:08 27 4
gpt4 key购买 nike

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

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

DataGrid: only the first part of the row is marked as "selected"

这显然很难看。我想选择整行,或者选择列来填充整个宽度,这会更好,但正如您所看到的,这是行不通的。

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

我找到了一个 similar question here ,并在那里发布了解决方法。这可能行得通,但我正在使用 MVVM 模式,因此 ItemsSource 在 ViewModel 中得到更新 我无法从那里想出一种方法,因为我无法访问 ActualWidth DataGridColumn 属性。此外,如果可能,我想只在 XAML 中执行此操作。

如果有任何帮助,我将不胜感激。谢谢!

编辑:因为我仍然不知道该怎么做,所以我开始了一个小赏金。我会很高兴有人能为我的问题做些什么的建议。再次感谢!

编辑 2:在 saus 的回答之后,我再次考虑了这些选项。问题是我需要在应用程序运行期间更新 WidthMinWidth 属性,所以不仅仅是在加载窗口之后。我已经尝试过做类似的事情

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

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

最佳答案

我建议使用您链接到的解决方法。它确实有效。在您的 View 的代码隐藏中,将以下内容添加到 InitializeComponent() 之后的构造函数中:

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

并将 SetMinWidths 定义为:

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 禁止代码隐藏中的代码”这件事有点误解。

但是如果您受样式指南的约束,或者您希望此逻辑可用于您应用中的所有数据网格,您可以创建一个附加行为来完成这样的工作:

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 ItemsSource="{Binding Table}" local:SetMinWidthToAutoAttachedBehaviour.SetMinWidthToAuto="true">

然后你的良心,以及你的代码隐藏,都会清楚。

关于c# - 如何设置 DataGridColumn 的宽度以适应内容 ("Auto"),但完全填充 MVVM 中 DataGrid 的可用空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4997596/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com