Sör*_*ren 23 c# wpf xaml datagrid mvvm
我有一个DataGrid包含一些数据的WPF .我想设置列的宽度,使内容适合并永远不会被裁剪(相反,水平滚动条应该变得可见).另外,我希望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>
Run Code Online (Sandbox Code Playgroud)
这显然不是开箱即用的,Width="Auto"因为它总是看起来像这样:

这看起来很丑陋.我想选择整行,或者更好的是填充整个宽度的列,但正如人们所看到的,这不起作用.
如果我Width="*"改用,列的内容会被裁剪掉,这对我来说更糟糕.
我在这里找到了一个类似的问题,并在那里发布了一个解决方法.这可能有效,但我正在使用MVVM模式,因此ItemsSource在ViewModel中得到更新,我无法想到从那里做到这一点的方法,因为我无法访问该ActualWidth属性DataGridColumn.另外,如果可能的话,我只想在XAML中这样做.
我将不胜感激任何帮助.谢谢!
编辑:由于我仍然不知道如何处理它,我开始小小的赏金.关于我可以对我的问题采取什么建议,我会非常高兴.再次感谢!
编辑2:在香肠'回答后,我再次考虑了这些选项.问题是我需要在应用程序运行期间更新Width和MinWidth属性,因此不仅在加载窗口后.我已经尝试过这样的事情了
column.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
column.MinWidth = column.ActualWidth;
column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
Run Code Online (Sandbox Code Playgroud)
在当底层被解雇的一些事件ItemsSource中的DataGrid被更新.然而,这是不行的,因为ActualWidth财产似乎并没有设置后改变Width上Auto.有没有选择以某种方式"重新"它以便ActualWidth更新属性?谢谢!
sau*_*aus 32
我建议使用您链接的解决方法.它确实有效.在视图的代码隐藏中,在InitializeComponent()之后将以下内容添加到构造函数中:
Griddy.Loaded += SetMinWidths; // I named my datagrid Griddy
Run Code Online (Sandbox Code Playgroud)
并将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);
}
}
Run Code Online (Sandbox Code Playgroud)
我假设您不想使用此解决方案的原因是您认为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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后对于要将此行为应用于的任何数据网格,添加以下内容:
<DataGrid ItemsSource="{Binding Table}" local:SetMinWidthToAutoAttachedBehaviour.SetMinWidthToAuto="true">
Run Code Online (Sandbox Code Playgroud)
然后你的良心以及你的代码隐藏将会很清楚.
使用在模板列内进行文本换行的 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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
63070 次 |
| 最近记录: |