我有一个包含一些数据的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"中是行不通的,因为它总是这样的:

这看起来很难看。我希望选择整个行,或者更好的是填充整个宽度的列,但正如人们所看到的,这是行不通的。
如果我使用Width="*",就会裁剪列的内容,这对我来说更糟了。
我找到了一个similar question here,并在那里发布了一个解决方案。这可能有效,但我使用的是MVVM模式,因此ItemsSource在ViewModel中得到更新,我无法从那里考虑一种方法,因为我无法访问DataGridColumn的ActualWidth属性。而且,如果可能的话,我只想在XAML中这样做。
我很感谢你的帮助。谢谢!
编辑:由于我仍然不知道该怎么做,所以我开始了一笔小小的赏金。如果有人能对我的问题做些什么,我会很高兴的。再次感谢!
编辑2:在索斯的回答之后,我又考虑了一下选项。问题是我需要在应用程序运行期间更新Width和MinWidth属性,所以不仅仅是在加载窗口之后。我已经试过这样做了
column.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
column.MinWidth = column.ActualWidth;
column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);在某些情况下,当ItemsSource的基础DataGrid正在更新时触发。但是,这不起作用,因为在设置ActualWidth上的Width之后,Auto属性似乎不会改变。是否有选项以某种方式“重新绘制”它,以便更新ActualWidth属性?谢谢!
发布于 2011-02-18 01:10:41
我建议使用你链接到的解决方法。确实有用。在视图的编解码器中,在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">然后你的良心,以及你的暗号,都将是清晰的。
发布于 2011-02-14 23:00:40
在模板列中使用文本包装的TextBlock:
<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>发布于 2011-02-17 09:28:19
这个怎么样:
对于您的列的MinWidth,您设置了一个绑定到dataGrid的ScrollContent的宽度,并使用一个转换器将此宽度除以列数
您需要为转换器后面的代码,但这将保持您的MVVM结构完整。
可能是一个很长的机会,但没有时间去尝试。
编辑:,我把更多的想法放在这个和那里,一个pb:如果你有一个很大的专栏和几个小的专栏,它将不能很好的工作。我认为所有的科尔都是相同的宽度,这显然不是这样的。
不过,你可能会想用这种方式探索。用转换器在宽度上使用绑定是我能想到的唯一可行的方法:因为在计算列的宽度时基本上需要考虑两个条件,所以没有简单的方法可以做到这一点。
https://stackoverflow.com/questions/4997596
复制相似问题