如何在WPF列表视图列的比例调整期间避免水平滚动条
本文关键字:调整期 滚动条 水平 WPF 列表 视图 | 更新日期: 2023-09-27 18:06:10
目标:在WPF网格中,当窗口大小改变时,以编程方式调整子ListView中的列的大小,保持相对列的大小,而不显示水平滚动条。
目前,比例调整的工作非常好,除了当我减少窗口的宽度,我将得到一个水平滚动条,只有少量的空间它滚动。我想知道这是否是由于宽度属性不考虑列之间的图形分隔符?还是…?
导致问题的部分是最后一节,我扩展最后一列的宽度以填充其余的空间。我不想减去我从试验中得到的神奇数字;错误(可能在一定程度上有效)。
. .是的,最终我将解释垂直滚动条的存在(或不存在),但现在我只想避免看到水平滚动条。
下面是调整ListView列大小的代码:
LV_FileList.SizeChanged += this.onLV_FileList_SizeChanged;
…
/// <summary>
/// Proportionally resize listview columns when listview size changes
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void onLV_FileList_SizeChanged(object sender, SizeChangedEventArgs e)
{
if ((sender is ListView) &&
(e.PreviousSize.Width > 0))
{
double total_width = 0;
GridViewColumnCollection gvcc = ((GridView)(sender as ListView).View).Columns;
foreach (GridViewColumn gvc in gvcc)
{
gvc.Width = (gvc.Width / e.PreviousSize.Width) * e.NewSize.Width;
total_width += gvc.Width;
}
//Increase width of last column to fit width of listview if integer division made the total width to small
if (total_width < e.NewSize.Width)
{
gvcc[gvcc.Count - 1].Width += (e.NewSize.Width - total_width);
}
}
}
我在有问题的部分添加了一个While循环,但它有不工作的不幸效果。ComputedHorizontalScrollBarVisibilityProperty的值永远不会随着最后一列的宽度递减而改变,所以它只是变为0,并为该列的宽度抛出一个无效值异常。我甚至尝试在循环中抛出对LV_FileList.UpdateLayout()的调用,认为也许listview控件的显示需要在水平滚动条消失之前刷新或其他东西。不行。
//Increase width of last column to fit width of listview if integer division made the total width to small
if (total_width < e.NewSize.Width)
{
gvcc[gvcc.Count - 1].Width += (e.NewSize.Width - total_width);
while ((Visibility)LV_FileList.GetValue(ScrollViewer.ComputedHorizontalScrollBarVisibilityProperty) == Visibility.Visible)
{
gvcc[gvcc.Count - 1].Width--;
//LV_FileList.UpdateLayout(); <-- doesn't help
}
}
这是我最后的结果。它还可以处理垂直滚动条。到目前为止,我发现的一个缺点是,当用户调整窗口大小时,水平滚动条有时会短暂闪烁。如果有人知道更好的方法,请发帖!谢谢!
/// <summary>
/// Proportionally resize listview columns when listview size changes
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void onLV_FileList_SizeChanged(object sender, SizeChangedEventArgs e)
{
if ((sender is ListView) &&
(e.PreviousSize.Width > 0))
{
double total_width = 0;
GridViewColumnCollection gvcc = ((GridView)(sender as ListView).View).Columns;
foreach (GridViewColumn gvc in gvcc)
{
gvc.Width = (gvc.Width / e.PreviousSize.Width) * e.NewSize.Width;
total_width += gvc.Width;
}
//Increase width of last column to fit width of listview if integer division made the total width to small
if (total_width < e.NewSize.Width)
{
gvcc[gvcc.Count - 1].Width += (e.NewSize.Width - total_width);
}
//Render changes to ListView before checking for horizontal scrollbar
this.AllowUIToUpdate();
//Decrease width of last column to eliminate scrollbar if it is displayed now
ScrollViewer svFileList = this.FindVisualChild<ScrollViewer>(LV_FileList);
while ((svFileList.ComputedHorizontalScrollBarVisibility != Visibility.Collapsed) && (gvcc[gvcc.Count - 1].Width > 1))
{
gvcc[gvcc.Count - 1].Width--;
this.AllowUIToUpdate();
}
}
}
/// <summary>
/// Threaded invocation to handle updating UI in resize loop
/// </summary>
private void AllowUIToUpdate()
{
DispatcherFrame dFrame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Render, new DispatcherOperationCallback(delegate(object parameter)
{
dFrame.Continue = false;
return null;
}), null);
Dispatcher.PushFrame(dFrame);
}
将HorizontalScrollBarVisibility
属性设置为disabled应该可以做到。
myListView.SetValue(ScrollViewer.HorizontalScrollBarVisibilityProperty,
ScrollBarVisibility.Disabled);
或在XAML…
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled">