返回顶部
首页 > 资讯 > 精选 >自动扩张WPF树型表格列宽问题怎么解决
  • 350
分享到

自动扩张WPF树型表格列宽问题怎么解决

2023-06-17 14:06:09 350人浏览 薄情痞子
摘要

今天小编给大家分享一下自动扩张WPF树型表格列宽问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。原问题如下:图1

今天小编给大家分享一下自动扩张WPF树型表格列宽问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

原问题如下:

自动扩张WPF树型表格列宽问题怎么解决

图1 问题描述

背景

树型控件在GIX4系统中已经被大量使用。这个控件是一年前其它同事在网上搜索到,再引入的。

一开始的时候,要解决这个问题,想到的最直接的方案是这样的:找到***列中的Expander控件(加号:自动扩张WPF树型表格列宽问题怎么解决),然后监听它的“Expanded”事件;在事件处理程序中,计算所需要的宽度,然后设置为控件的宽度。

按照这个方案去实际写代码时,发现并没有想象中那么简单,发现了很多问题。例如,Expander并不是Expander控件,而是一个ToggleButton,而且是写在模板中的,TreeGridRowPresenter中的Expander的类型也只是UIElement,也就是说,不能把Expander从UIElement转换为ToggleButton,这样程序会写得很死。又如,如何计算***列的所需要宽度。

这些问题是要上面提及的BUG所需要解决的:

四个待解决的问题

何时触发是最合适的?在何处触发调整宽度的代码?

如何找到树型控件的所有GridViewRowPresenter。

GridViewRowPresenter中,如何把***列的控件找到。

***列控件的组成结构是怎么样的,它所需要的大小如何求出,是否可以直接使用Measure和DesiredSize。

一步一步解决

***个问题,何时触发这个功能?其实我是要在点击后,当子节点都加载好后,然后计算出合适的大小,再设置给列对象。我先在TreeListView的OnExpanded事件处理程序中尝试编写代码获取每一个TreeListView,但是发现这个事件在发生时,所有的子节点并没有生成,所以不能通过ItemContainerGenerator.GetContainerForItem方法获取到窗口,此方案失败。接着,我查看了ItemsControl的接口声明,发现ItemContainerGenerator属性有事件StatusChanged。所以我就改为监听这个事件,并判断如果当它的Status变为ContainersGenerated时,就表示所有子节点已经生成了。代码如下:

this.ItemContainerGenerator.StatusChanged += (o, e) =>     {    if (this.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)      {          this.AdjustFirstColumnWidth();       }     };

但是同样发现新的问题,这时候虽然窗口对象TreeListView已经生成,但是它下面的所有Visual Child都没有生成,这样同样无法获取到它里面用来显示每一行的GridRowPresenter。所以只有改成了这样:

 public TreeListViewItem()     {    this.PrepareToAdjustFirstColumnWidth();     }     private void PrepareToAdjustFirstColumnWidth()     {      this.ItemContainerGenerator.StatusChanged += (o, e) =>       {         if (this.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)        {           if (this.Items.Count > 0)           {         var item = this.Items[this.Items.Count - 1];    var treeItem = this.ItemContainerGenerator.ContainerFromItem(item) as TreeListViewItem;    treeItem.Loaded += (oo, ee) =>       {          this.AdjustFirstColumnWidth();       };        }        }        };     }

这样,***一个孩子的可视内容都加载好后,才会触发调整宽度的代码。

第二个问题比较简单,看了TreeListView的源码后,发现它在TreeListViewItem类的模板中使用了GridViewRowPresenter类,然后为它定义了名字:“PART_Header”。

private TreeGridViewRowPresenter FindGridRow()    {    var rowPresenter = this.Template.FindName("PART_Header", this) as TreeGridViewRowPresenter;     return rowPresenter;    }

要解决第三个问题,我们需要知道GridViewRowPresenter中如何生成一行,并知道***生成的控件结构。先看看GridViewRowPresenter***生成的控件结构,这里我使用的是Snoop:

自动扩张WPF树型表格列宽问题怎么解决

图2 用Snoop查看TreeGridViewRowPresenter的可视化结构

我们发现,GridViewRowPresenter下只是简单的包含了几个可视元素,它们刚好是每一列所显示的内容。再查看GridViewRowPresenter的源代码,发现它拥有以下属性:public GridViewColumnCollection Columns{get;set;}、internal UIElementCollection InternalCollection{get;set;},进一步分析后,我猜测性地得出以下结论:GridViewRowPresenter.InternalCollection简单地包含了所有列的显示元素,它会根据Columns属性中各行对这些可视元素进行维护,让它们显示得跟表格一样。

至此,第三个问题解决了:

var firstColumn = VisualTreeHelper.GetChild(rowPresenter, 0) as UIElement;

***一个问题,是过程中最麻烦的一个问题。我们看到,图2中该行下的***个元素是***列的显示元素,显示了“2.1”。但是文本左边的Expander控件却是TreeGridViewRowPresenter的***一个可视化孩子。而且缩进并不是一个控件。那么这是怎么一回事呢?看了TreeGridViewRowPresenter的源码后,发现原来是它主动把Expander放在了***:

public class TreeGridViewRowPresenter : GridViewRowPresenter    {      protected override System.windows.Media.Visual GetVisualChild(int index)       {         // Last element is always the expander       // called by render engine      if (index < base.VisualChildrenCount) return base.GetVisualChild(index);     if (index == base.VisualChildrenCount) return this.lbRowNo;     return this.Expander;        }      protected override int VisualChildrenCount     {      get        {            // Last element is always the expander          if (this.Expander != null)            return base.VisualChildrenCount + 2;       else         return base.VisualChildrenCount + 1;       }       }    }

而文本前面先显示缩进,然后再显示Expander的原因是由于TreeGridViewRowPresenter类重写了FrameworkElement.ArrangeOverride方法。在该方法中,它把***列的元素显示的长度变短在之前显示一段缩进的空白和Expander控件:

protected override Size ArrangeOverride(Size arrangeSize)     {     Size s = base.ArrangeOverride(arrangeSize);    if (this.Columns == null || this.Columns.Count == 0) return s;    UIElement expander = this.Expander;    double current = 0;    double max = arrangeSize.Width;     for (int x = 0; x < this.Columns.Count; x++)    {      GridViewColumn column = this.Columns[x];      // Actual index needed for column reorder      UIElement uiColumn = (UIElement)base.GetVisualChild((int)ActualIndexProperty.GetValue(column, null));     // Compute column width      double w = Math.Min(max, (Double.IsNaN(column.Width)) ? (double)DesiredWidthProperty.GetValue(column, null) : column.Width);     // First column indent      if (x == 0 && expander != null)      {        double indent = FirstColumnIndent + expander.DesiredSize.Width;       uiColumn.Arrange(new Rect(current + indent, 0, w - indent, arrangeSize.Height));          }         else       {          uiColumn.Arrange(new Rect(current, 0, w, arrangeSize.Height));         }      max -= w;         current += w;        }      // Show expander     if (expander != null)        {      expander.Arrange(new Rect(this.FirstColumnIndent, 0, expander.DesiredSize.Width, expander.DesiredSize.Height));      }      return s;    }

分析到这里,就知道如何计算出***列的最终宽度了:

private double GetFirstColumnDesiredWidth()     {      var rowPresenter = this.FindGridRow();     if (VisualTreeHelper.GetChildrenCount(rowPresenter) <= 0) return 0;     //GridViewRowPresenter中的每一个元素表示一列。     var firstColumn = VisualTreeHelper.GetChild(rowPresenter, 0) as UIElement;    var desiredWidth = firstColumn.DesiredSize.Width;     //需要的宽度前,需要加上列的缩进和Expander的宽度。     var indent = rowPresenter.FirstColumnIndent + rowPresenter.Expander.DesiredSize.Width;      return indent + desiredWidth + ENSURE_SIZE;     }

以上就是“自动扩张WPF树型表格列宽问题怎么解决”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: 自动扩张WPF树型表格列宽问题怎么解决

本文链接: https://lsjlt.com/news/289906.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 自动扩张WPF树型表格列宽问题怎么解决
    今天小编给大家分享一下自动扩张WPF树型表格列宽问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。原问题如下:图1 ...
    99+
    2023-06-17
  • java创建表格序号自增问题怎么解决
    在Java中,可以通过使用一个变量来记录表格的序号,并在每次创建新的表格时增加该变量的值来实现表格序号的自增。以下是一个示例代码,演...
    99+
    2023-10-18
    java
  • Android Compose Column列表不自动刷新问题如何解决
    本篇内容介绍了“Android Compose Column列表不自动刷新问题如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能...
    99+
    2023-07-05
  • 怎么解决win8自动断网问题
    这篇文章将为大家详细讲解有关怎么解决win8自动断网问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。首先“开始”菜单,直接选择控制面板,在弹出的“控制面板”窗口,直接点击“网络和共享中心”。然后可以在“...
    99+
    2023-06-27
  • dedecms自定义表单用js代替联动类型解决联动问题
    最近用DEDEcms完成一个自定义表单,要用到地区的三级级联,地区肯定要使用option下拉框,如果让人一个个填肯定不行,DEDECMS内置的联动类型被注释掉了,网上有解决联动类型的例子,但存在后台信息的是枚举,都是数字...
    99+
    2022-06-12
    dedecms 自定义表单 联动类型
  • 怎么解决SpringBoot自动装配bean找不到类型的问题
    这篇文章主要介绍“怎么解决SpringBoot自动装配bean找不到类型的问题”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么解决SpringBoot自动装配bean找不到类型的问题”文章能帮助大...
    99+
    2023-06-29
  • 域名列表不能为空问题怎么解决
    如果您在创建域名列表时遇到“域名列表不能为空”的问题,请检查以下几点:1. 您是否正确输入了域名列表。请确保每个域名之间用逗号或换行...
    99+
    2023-06-10
    域名列表 域名
  • Python列表和字典踩坑问题怎么解决
    这篇“Python列表和字典踩坑问题怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python列表和字典踩坑问题怎么...
    99+
    2023-06-30
  • oracle数据库表空间扩容的问题怎么解决
    本文小编为大家详细介绍“oracle数据库表空间扩容的问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“oracle数据库表空间扩容的问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1.查看表...
    99+
    2023-07-05
  • sqlserver服务自动停止问题怎么解决
    要解决SQL Server服务自动停止的问题,可以尝试以下几个步骤:1. 检查系统事件日志:打开Windows事件查看器,查看系统事...
    99+
    2023-09-28
    sqlserver
  • win11自动黑屏关闭问题怎么解决
    这篇文章主要介绍“win11自动黑屏关闭问题怎么解决”,在日常操作中,相信很多人在win11自动黑屏关闭问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”win11自动黑屏关闭问题怎么解决”的疑惑有所...
    99+
    2023-07-02
  • excel表格不受控制自己跳动怎么解决
    如果Excel表格不受控制地跳动,可能是由于以下几个原因:1. 键盘或鼠标问题:检查键盘和鼠标是否正常工作,尝试更换键盘或鼠标,或者...
    99+
    2023-09-11
    excel
  • Vue编程格式化代码属性自动换行问题怎么解决
    这篇文章主要介绍“Vue编程格式化代码属性自动换行问题怎么解决”,在日常操作中,相信很多人在Vue编程格式化代码属性自动换行问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue编程格式化代码属性自...
    99+
    2023-07-02
  • python列表切片超出长度问题怎么解决
    当切片的结束位置超出列表的长度时,Python会自动将结束位置设置为列表的最后一个元素的索引加1。因此,可以通过判断切片的结束位置是...
    99+
    2024-02-29
    python
  • 怎么解决数据库分库分表无限扩容问题
    这篇文章主要讲解了“怎么解决数据库分库分表无限扩容问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么解决数据库分库分表无限扩容问题”吧!单体应用每个创业...
    99+
    2024-04-02
  • Python字符串类型及格式化问题怎么解决
    这篇文章主要讲解了“Python字符串类型及格式化问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python字符串类型及格式化问题怎么解决”吧!一、字符串类型1)字符串是字符的序...
    99+
    2023-07-05
  • springboot无法自动装配的问题怎么解决
    本篇文章为大家展示了springboot无法自动装配的问题怎么解决,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。springboot 无法自动装配@Autowired 报错:无法自动装配基本上是因为...
    99+
    2023-06-26
  • iOS列表上拉(平滑加载数据)自动加载数据的问题解决
    项目需求 我的的列表需要改变,原来的分页加载采用的是MJRefresh框架进行加载更多数据,这需要有一个上拉动作才能触发,而我的产品的意思是当快要滑动到底部时自动加载下一页数据。我...
    99+
    2022-05-19
    ios 上拉 加载
  • Vue读取HTMLCollection列表的length为0问题怎么解决
    这篇“Vue读取HTMLCollection列表的length为0问题怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“...
    99+
    2023-06-30
  • vue使用echarts图表自适应问题怎么解决
    在Vue中使用ECharts图表时,可以通过监听窗口大小变化,动态调整图表的大小以实现自适应。具体步骤如下: 在Vue组件中引入E...
    99+
    2024-03-08
    vue echarts
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作