WPF数据网格不';列宽缩小时,t将缩小
我在WPF中使用DataGrid,希望它收缩到只适合其列的宽度。对于初始渲染,它可以很好地实现这一点。当我调整列的大小使其更宽时,网格也会增长。但是,如果我调整列的大小使其再次变窄,我会在列的右侧得到空白(我可以看到列标题灰色区域延伸到列之外) 我想让数据网格用列缩小它的宽度,这样我就不会在右边留下空白。我已经试着调试代码,据我所知,问题出在DataGridCellsPanel中,但我看不到任何地方可以修复宽度测量WPF数据网格不';列宽缩小时,t将缩小,wpf,wpftoolkit,wpfdatagrid,Wpf,Wpftoolkit,Wpfdatagrid,我在WPF中使用DataGrid,希望它收缩到只适合其列的宽度。对于初始渲染,它可以很好地实现这一点。当我调整列的大小使其更宽时,网格也会增长。但是,如果我调整列的大小使其再次变窄,我会在列的右侧得到空白(我可以看到列标题灰色区域延伸到列之外) 我想让数据网格用列缩小它的宽度,这样我就不会在右边留下空白。我已经试着调试代码,据我所知,问题出在DataGridCellsPanel中,但我看不到任何地方可以修复宽度测量 任何帮助都将不胜感激。我很久以前就遇到过这个问题,对此我非常恼火,以至于我做了一
任何帮助都将不胜感激。我很久以前就遇到过这个问题,对此我非常恼火,以至于我做了一个丑陋的修复。它不漂亮,但它完成了任务。首先,这只是一个问题,当水平滚动条不可见时,所以我们需要对它的引用。这段代码必须在所有DataGridColum运行一次ns已经加载(在我的例子中,都是在Xaml中,所以加载的事件)并且它没有考虑添加/删除DataGridColumns,但是这是一个简单的修复方法
<DataGrid Name="c_dataGrid"
Loaded="c_dataGrid_Loaded"
...>
<DataGrid.Columns>
<DataGridTextColumn ..."/>
<DataGridTextColumn ..."/>
<!-- ... -->
如果您有更好的方法,请告诉我:)
public static T GetVisualChild(对象父对象),其中T:Visual
{
DependencyObject DependencyObject=作为DependencyObject的父对象;
返回InternalGetVisualChild(dependencyObject);
}
私有静态T InternalGetVisualChild(DependencyObject父对象),其中T:Visual
{
T child=默认值(T);
int numVisuals=VisualTreeHelper.GetChildrenCount(父级);
对于(int i=0;i
这是一个很好的解决方案。我稍微调整了它,使其改为设置MaxWidth属性。这解决了网格扩展超出可视父对象约束的问题。我还将其转换为行为,以便更好地封装它
这就是我的结局
public class UpdateWidthOnColumnResizedBehavior : Behavior<DataGrid>
{
private static readonly DependencyPropertyDescriptor Descriptor;
static UpdateWidthOnColumnResizedBehavior()
{
Descriptor = DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn));
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Columns.CollectionChanged += OnColumnsCollectionChanged;
foreach (var column in AssociatedObject.Columns)
{
AddListener(column);
}
}
void OnColumnsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (var column in e.NewItems.OfType<DataGridColumn>())
{
AddListener(column);
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (var column in e.OldItems.OfType<DataGridColumn>())
{
RemoveListener(column);
}
break;
case NotifyCollectionChangedAction.Replace:
foreach (var column in e.NewItems.OfType<DataGridColumn>())
{
AddListener(column);
}
foreach (var column in e.OldItems.OfType<DataGridColumn>())
{
RemoveListener(column);
}
break;
}
}
protected override void OnDetaching()
{
base.OnDetaching();
foreach (var column in AssociatedObject.Columns)
{
RemoveListener(column);
}
}
private void AddListener(DataGridColumn column)
{
Descriptor.AddValueChanged(column, ResizeGrid);
}
private void RemoveListener(DataGridColumn column)
{
Descriptor.RemoveValueChanged(column, ResizeGrid);
}
private void ResizeGrid(object sender, EventArgs e)
{
var columnsWidth = AssociatedObject.Columns.Sum(c => c.ActualWidth);
AssociatedObject.MaxWidth = columnsWidth + 2;
AssociatedObject.InvalidateMeasure();
}
}
公共类UpdateWidthOnColumnResizedBehavior:行为
{
私有静态只读DependencyPropertyDescriptor描述符;
静态UpdateWidthOnColumnResizedBehavior()
{
描述符=DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty,typeof(DataGridColumn));
}
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.Columns.CollectionChanged+=OnColumnsCollectionChanged;
foreach(AssociatedObject.Columns中的var列)
{
AddListener(列);
}
}
无效OnColumnsCollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
开关(电动)
{
案例NotifyCollectionChangedAction。添加:
foreach(e.NewItems.OfType()中的var列)
{
AddListener(列);
}
打破
案例NotifyCollectionChangedAction。删除:
foreach(e.OldItems.OfType()中的var列)
{
RemoveListener(列);
}
打破
案例通知收集更改操作。替换:
foreach(e.NewItems.OfType()中的var列)
{
AddListener(列);
}
foreach(e.OldItems.OfType()中的var列)
{
RemoveListener(列);
}
打破
}
}
附加时受保护的覆盖无效()
{
base.OnDetaching();
foreach(AssociatedObject.Columns中的var列)
{
RemoveListener(列);
}
}
私有void AddListener(DataGridColumn列)
{
Descriptor.AddValueChanged(列,ResizeGrid);
}
私有void RemoveListener(DataGridColumn列)
{
Descriptor.RemoveValueChanged(列,ResizeGrid);
}
私有void ResizeGrid(对象发送方,事件参数e)
{
var columnsWidth=AssociatedObject.Columns.Sum(c=>c.ActualWidth);
AssociatedObject.MaxWidth=columnsWidth+2;
AssociatedObject.InvalidateMeasure();
}
}
关于两个网格的宽度协调,我仍有一些问题需要解决,但对于其中一个网格来说,这似乎是可行的。您的两种方法似乎都有一个小问题。当我将最左边的列向右拖动时,整个网格的大小正在调整/滚动(不幸的是,我没有足够的声誉来发布图像) 所以我修改了jjrdk ResizeGrid函数,它计算最后一列的宽度,并将其一直扩展到左侧。栅格水平对齐和水平内容对齐必须设置为 水平对齐
void ResizeGrid(object sender, EventArgs e)
{
var scroll = ExTreeHelper.FindVisualChild<ScrollViewer>(AssociatedObject);
if (scroll != null && null != AssociatedObject.Columns && AssociatedObject.Columns.Count > 0)
{
var lastColumn = AssociatedObject.Columns.Last();
double dataGridWidth = AssociatedObject.Columns.Sum(c => c.ActualWidth) + 2.0;
if (scroll.ComputedHorizontalScrollBarVisibility != Visibility.Visible)
{
RemoveListener(lastColumn);
AssociatedObject.Columns.Last().Width =
AssociatedObject.Columns.Last().Width.DisplayValue + scroll.ViewportWidth - dataGridWidth;
AssociatedObject.Width = dataGridWidth + scroll.ViewportWidth - dataGridWidth;
AddListener(lastColumn);
}
else
{
AssociatedObject.HorizontalAlignment = HorizontalAlignment.Stretch;
AssociatedObject.HorizontalContentAlignment = HorizontalAlignment.Stretch;
AssociatedObject.Width = double.NaN;
}
} }
void ResizeGrid(对象发送方,事件参数e)
{
var scroll=ExTreeHelper.FindVisualChild(关联对象);
如果(滚动!=null&&null!=AssociatedObject.Columns&&AssociatedObject.Columns.Count>0)
{
var lastColumn=AssociatedObject.Columns.Last();
double dataGridWidth=AssociatedObject.Columns.Sum(c=>c.ActualWidth)+2.0;
if(scroll.ComputedHorizontalScrollBarVisibility!=可见性.Visible)
{
RemoveListener(最后一列);
AssociatedObject.Columns.Last().Width=
关联对象
public static T GetVisualChild<T>(object parent) where T : Visual
{
DependencyObject dependencyObject = parent as DependencyObject;
return InternalGetVisualChild<T>(dependencyObject);
}
private static T InternalGetVisualChild<T>(DependencyObject parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}
public class UpdateWidthOnColumnResizedBehavior : Behavior<DataGrid>
{
private static readonly DependencyPropertyDescriptor Descriptor;
static UpdateWidthOnColumnResizedBehavior()
{
Descriptor = DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn));
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Columns.CollectionChanged += OnColumnsCollectionChanged;
foreach (var column in AssociatedObject.Columns)
{
AddListener(column);
}
}
void OnColumnsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (var column in e.NewItems.OfType<DataGridColumn>())
{
AddListener(column);
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (var column in e.OldItems.OfType<DataGridColumn>())
{
RemoveListener(column);
}
break;
case NotifyCollectionChangedAction.Replace:
foreach (var column in e.NewItems.OfType<DataGridColumn>())
{
AddListener(column);
}
foreach (var column in e.OldItems.OfType<DataGridColumn>())
{
RemoveListener(column);
}
break;
}
}
protected override void OnDetaching()
{
base.OnDetaching();
foreach (var column in AssociatedObject.Columns)
{
RemoveListener(column);
}
}
private void AddListener(DataGridColumn column)
{
Descriptor.AddValueChanged(column, ResizeGrid);
}
private void RemoveListener(DataGridColumn column)
{
Descriptor.RemoveValueChanged(column, ResizeGrid);
}
private void ResizeGrid(object sender, EventArgs e)
{
var columnsWidth = AssociatedObject.Columns.Sum(c => c.ActualWidth);
AssociatedObject.MaxWidth = columnsWidth + 2;
AssociatedObject.InvalidateMeasure();
}
}
void ResizeGrid(object sender, EventArgs e)
{
var scroll = ExTreeHelper.FindVisualChild<ScrollViewer>(AssociatedObject);
if (scroll != null && null != AssociatedObject.Columns && AssociatedObject.Columns.Count > 0)
{
var lastColumn = AssociatedObject.Columns.Last();
double dataGridWidth = AssociatedObject.Columns.Sum(c => c.ActualWidth) + 2.0;
if (scroll.ComputedHorizontalScrollBarVisibility != Visibility.Visible)
{
RemoveListener(lastColumn);
AssociatedObject.Columns.Last().Width =
AssociatedObject.Columns.Last().Width.DisplayValue + scroll.ViewportWidth - dataGridWidth;
AssociatedObject.Width = dataGridWidth + scroll.ViewportWidth - dataGridWidth;
AddListener(lastColumn);
}
else
{
AssociatedObject.HorizontalAlignment = HorizontalAlignment.Stretch;
AssociatedObject.HorizontalContentAlignment = HorizontalAlignment.Stretch;
AssociatedObject.Width = double.NaN;
}
} }