目标:在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
}
}
答案 0 :(得分:0)
将HorizontalScrollBarVisibility
属性设置为禁用应该这样做。
myListView.SetValue(ScrollViewer.HorizontalScrollBarVisibilityProperty,
ScrollBarVisibility.Disabled);
或者在XAML ......
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
答案 1 :(得分:0)
这是我最终的结果。它也处理垂直滚动条。到目前为止我发现的一个缺点是,当用户调整窗口大小时,水平滚动条有时会短暂闪烁。如果有人知道更好的方式,请发布!谢谢!
/// <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);
}