如何在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
                }
            }

如何在WPF列表视图列的比例调整期间避免水平滚动条

这是我最后的结果。它还可以处理垂直滚动条。到目前为止,我发现的一个缺点是,当用户调整窗口大小时,水平滚动条有时会短暂闪烁。如果有人知道更好的方法,请发帖!谢谢!

        /// <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">