如何在WPF ListView列的比例大小调整期间避免水平滚动条

时间:2016-09-07 23:06:50

标签: c# wpf listview scrollbar window-resize

目标:在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循环,但它有不起作用的不幸效果。 ComputedHorizo​​ntalScrollBarVisibilityProperty值永远不会随着最后一列的宽度递减而更改,因此它只会转到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
                }
            }

2 个答案:

答案 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);
    }