代码之家  ›  专栏  ›  技术社区  ›  oliver

所有者绘制的列表视图未正确自动调整列的大小

  •  1
  • oliver  · 技术社区  · 6 年前

    my listview(winforms)派生的类自己绘制单元格,以从二维字符串数组中获得类似Excel的外观。

    自动调整以某种方式工作,但不完全正确。条目较大的列更宽,但省略号仍然出现在最大的字符串上。

    如何使AutoSize正常工作?

    btw:由于糟糕的性能,DataGridView是不需要的。

    tableview测试.cs:。

    public class tableviewtest:form
    {
    private liftqd.tableview表视图1;
    
    公共表视图测试()
    {
    this.tableview 1=new liftqd.tableview();
    this.suspendlayout();
    this.tableview1.dock=system.windows.forms.dockstyle.fill;
    this.tableview1.headerStyle=system.windows.forms.columnHeaderStyle.nonclickable;
    this.tableview1.location=new system.drawing.point(0,0);
    this.tableview1.name=“tableview1”;
    this.tableview1.ownerdraw=真;
    this.tableview1.scrollable=false;
    this.tableview1.size=new system.drawing.size(284261);
    this.tableview1.tabindex=0;
    this.tableview1.useCompatibleStateImageBehavior=false;
    this.tableview1.view=system.windows.forms.view.details;
    this.autoscaleDimensions=新系统.drawing.sizef(6f,13f);
    this.autoscalemode=system.windows.forms.autoscalemode.font;
    this.clientSize=新系统.drawing.size(284261);
    this.controls.add(this.tableview1);
    this.name=“TableViewTest”;
    this.text=“TableViewTest”;
    此。重新分配(错误);
    
    tableview1.table=new table(new string[,]“abcdefg”,“hijklmnop”,“1234567”,“所有好孩子都上天堂”);
    }
    }
    < /代码> 
    
    

    表格视图.cs:。

    public class tableview:listview
    {
    表表;
    bool是调整lastcolumn;
    
    公共表视图()
    {
    双缓冲=真;
    view=view.details;
    
    //我们自己画网格线
    网格线=假;
    ownerdraw=真;
    可滚动=假;
    headerStyle=columnHeaderStyle.nonclickable;
    }
    
    受保护的覆盖void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs E)
    {
    if(e.columnindex==columns.count-1)
    {
    e.graphics.fillRectangle(SystemBrushes.Window,e.Bounds.Left,e.Bounds.Top,e.Bounds.Width-1,e.Bounds.Height-1);
    }
    其他的
    {
    e.graphics.fillRectangle(SystemBrushes.Control,e.Bounds.Left,e.Bounds.Top,e.Bounds.Width-1,e.Bounds.Height-1);
    e.graphics.drawline(systempens.activeborder,e.bounds.left,e.bounds.bottom-1,e.bounds.right-1,e.bounds.bottom-1);
    e.graphics.drawline(systempens.activeborder,e.bounds.right-1,e.bounds.bottom-1,e.bounds.right-1,e.bounds.top);
    e.drawtext(textformflags.horizontalcenter textformflags.verticalcenter);
    }
    }
    
    受保护的覆盖void OnDrawSubitem(DrawListViewSubitemEventArgs e)
    {
    if(e.columnindex==columns.count-1)
    {
    e.graphics.fillRectangle(SystemBrushes.Window,e.Bounds.Left,e.Bounds.Top,e.Bounds.Width-1,e.Bounds.Height-1);
    }
    else if(e.columnindex==0)
    {
    e.graphics.fillRectangle(SystemBrushes.Control,e.Bounds.Left,e.Bounds.Top,e.Bounds.Width-1,e.Bounds.Height-1);
    e.graphics.drawline(systempens.activeborder,e.bounds.left,e.bounds.bottom-1,e.bounds.right-1,e.bounds.bottom-1);
    e.graphics.drawline(systempens.activeborder,e.bounds.right-1,e.bounds.bottom-1,e.bounds.right-1,e.bounds.top);
    e.drawtext(textformflags.horizontalcenter textformflags.verticalcenter);
    }
    其他的
    {
    e.graphics.fillRectangle(SystemBrushes.Window,e.Bounds.Left,e.Bounds.Top,e.Bounds.Width-1,e.Bounds.Height-1);
    e.graphics.drawline(systempens.activeborder,e.bounds.left,e.bounds.bottom-1,e.bounds.right-1,e.bounds.bottom-1);
    e.graphics.drawline(systempens.activeborder,e.bounds.right-1,e.bounds.bottom-1,e.bounds.right-1,e.bounds.top);
    e.drawtext(textformFlags.verticalcenter textformFlags.singleline textformFlags.glyphOverhangPadding textformFlags.wordEllipsis);
    }
    
    }
    
    公共int tablewidth
    {
    得到
    {
    if(columns.count<2)返回0;
    返回项[items.count-1].subitems[columns.count-2].bounds.right;
    }
    }
    
    公共int tableheight
    {
    得到
    {
    if(items.count==0)返回0;
    返回项[items.count-1].bounds.bottom;
    }
    }
    
    //设置最后一列(空)的大小,以填充客户端区域
    void AdjustLastColumn()。
    {
    如果(!)调整最后一列)
    {
    IsAdjustingLastColumn=真;
    
    if(columns.count>0)columns[columns.count-1].width=math.max(clientsize.width tablewidth,0);
    
    IsAdjustingLastColumn=false;
    }
    }
    
    protected override void onresize(事件参数e)
    {
    adjustLastColumn();
    base.onresize(e);
    }
    
    Protected Override void OnColumnWidthChanged(ColumnWidthChangedEventargs E)
    {
    adjustLastColumn();
    底座。管道已更改(e);
    }
    
    Protected Override void OnColumnWithChanging(ColumnWidthChangingEventArgs E)
    {
    adjustLastColumn();
    底座。管道悬挂(E);
    }
    
    string getexcelcolumnname(int columnnumber)
    {
    利息股利=列数;
    string columnname=string.empty;
    模;
    
    同时(股息>0)
    {
    模=(股息-1)%26;
    columnname=convert.tochar(65+modulo).toString()+columnname;
    股息=(利息)((股息-模块)/26);
    }
    
    返回columnname;
    }
    
    公用表
    {
    get返回新表(table);
    设置
    {
    表=新表(值);
    
    如果(桌子)!=空)
    {
    int columncount=table.columncount;
    int rowcount=table.rowcount;
    
    //行名称(行号)的一个未命名列
    列。添加(“”);
    
    对于(int i=0;i<columncount;i++)
    {
    columns.add(getExcelColumnName(i+1));
    }
    
    //另一个将填充剩余客户机区域的空列
    columns.add(“”);
    
    对于(int j=0;j<rowcount;j++)
    {
    listviewitem lvi=新的listviewitem((j+1).toString());
    
    lvi.useitemstyleforsubitems=false;
    
    对于(int i=0;i<columncount;i++)
    {
    lvi.subitems.add(表[i,j]);
    }
    
    添加项(LVI);
    }
    
    自动调整大小列(ColumnHeaderAutoResizeStyle.HeaderSize);
    AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
    
    adjustLastColumn();
    }
    }
    }
    }
    < /代码> 
    
    

    表.cs:。

    公共类表 { 字符串[,]数据; 字符串名称“”; 字符串信息“”; 公共字符串名称 { 获取返回名称; 设置if(值!=null)name=value;否则name=“; } 公共字符串信息 { 获取返回信息; 设置if(值!=null)info=value;else info=“; } 公用表(string[,]originaldata) { data=(string[,])(originaldata.clone()); } 公用表(Table OriginalData) { data=(string[,])(originaldata.data.clone()); 字符串名称=originaldata.name; string info=originaldata.info; } public int rowcount get return data.getlength(1); public int columncount get return data.getlength(0); 公共字符串this[int xindex,int yindex] { 得到 { if(xindex>=0&xindex<data.getlength(0)&yindex>=0&yindex<data.getlength(1)) 返回数据[xindex,yindex]; 其他的 “返回”; } } } < /代码> <但不完全是。条目较大的列更宽,但省略号仍然出现在最大的字符串上。

    如何使AutoSize正常工作?

    btw:由于糟糕的性能,DataGridView是不需要的。

    enter image description here

    表格视图测试.cs:

    public class TableViewTest : Form
    {
        private LiftQD.TableView tableView1;
    
        public TableViewTest()
        {
            this.tableView1 = new LiftQD.TableView();
            this.SuspendLayout();
            this.tableView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tableView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
            this.tableView1.Location = new System.Drawing.Point(0, 0);
            this.tableView1.Name = "tableView1";
            this.tableView1.OwnerDraw = true;
            this.tableView1.Scrollable = false;
            this.tableView1.Size = new System.Drawing.Size(284, 261);
            this.tableView1.TabIndex = 0;
            this.tableView1.UseCompatibleStateImageBehavior = false;
            this.tableView1.View = System.Windows.Forms.View.Details;
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 261);
            this.Controls.Add(this.tableView1);
            this.Name = "TableViewTest";
            this.Text = "TableViewTest";
            this.ResumeLayout(false);
    
            tableView1.Table = new Table(new String[,]{{"abcdefg","hijklmnop"},{"1234567","all good children go to heaven"}});
        }
    }
    

    TableView.cs:

    public class TableView: ListView
    {
        Table table;
        bool isAdjustingLastColumn;
    
        public TableView()
        {
            DoubleBuffered = true;
            View = View.Details;
    
            // we draw gridlines ourselves
            GridLines = false;
            OwnerDraw = true;
            Scrollable = false;
            HeaderStyle = ColumnHeaderStyle.Nonclickable;
        }
    
        protected override void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e)
        {
            if (e.ColumnIndex == Columns.Count-1)
            {
                e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds.Left, e.Bounds.Top, e.Bounds.Width-1, e.Bounds.Height-1);
            }
            else
            {
                e.Graphics.FillRectangle(SystemBrushes.Control, e.Bounds.Left, e.Bounds.Top, e.Bounds.Width-1, e.Bounds.Height-1);
                e.Graphics.DrawLine(SystemPens.ActiveBorder, e.Bounds.Left, e.Bounds.Bottom-1, e.Bounds.Right-1, e.Bounds.Bottom-1);
                e.Graphics.DrawLine(SystemPens.ActiveBorder, e.Bounds.Right-1, e.Bounds.Bottom-1, e.Bounds.Right-1, e.Bounds.Top);
                e.DrawText(TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
            }
        }
    
        protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
        {
            if (e.ColumnIndex == Columns.Count-1)
            {
                e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds.Left, e.Bounds.Top, e.Bounds.Width-1, e.Bounds.Height-1);
            }
            else if (e.ColumnIndex == 0)
            {
                e.Graphics.FillRectangle(SystemBrushes.Control, e.Bounds.Left, e.Bounds.Top, e.Bounds.Width-1, e.Bounds.Height-1);
                e.Graphics.DrawLine(SystemPens.ActiveBorder, e.Bounds.Left, e.Bounds.Bottom-1, e.Bounds.Right-1, e.Bounds.Bottom-1);
                e.Graphics.DrawLine(SystemPens.ActiveBorder, e.Bounds.Right-1, e.Bounds.Bottom-1, e.Bounds.Right-1, e.Bounds.Top);
                e.DrawText(TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
            }
            else
            {
                e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds.Left, e.Bounds.Top, e.Bounds.Width-1, e.Bounds.Height-1);
                e.Graphics.DrawLine(SystemPens.ActiveBorder, e.Bounds.Left, e.Bounds.Bottom-1, e.Bounds.Right-1, e.Bounds.Bottom-1);
                e.Graphics.DrawLine(SystemPens.ActiveBorder, e.Bounds.Right-1, e.Bounds.Bottom-1, e.Bounds.Right-1, e.Bounds.Top);
                e.DrawText(TextFormatFlags.VerticalCenter | TextFormatFlags.SingleLine | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.WordEllipsis);
            }
    
        }
    
        public int TableWidth
        {
            get
            {
                if (Columns.Count < 2) return 0;
                return Items[Items.Count-1].SubItems[Columns.Count-2].Bounds.Right;
            }
        }
    
        public int TableHeight
        {
            get
            {
                if (Items.Count == 0) return 0;
                return Items[Items.Count-1].Bounds.Bottom;
            }
        }
    
        // sets the size of the last (empty) column so as to fill up the client area
        void adjustLastColumn()
        {
            if (!isAdjustingLastColumn)
            {
                isAdjustingLastColumn = true;
    
                if (Columns.Count > 0) Columns[Columns.Count-1].Width = Math.Max(ClientSize.Width-TableWidth,0);
    
                isAdjustingLastColumn = false;
            }
        }
    
        protected override void OnResize(EventArgs e)
        {
            adjustLastColumn();
            base.OnResize(e);
        }
    
        protected override void OnColumnWidthChanged(ColumnWidthChangedEventArgs e)
        {
            adjustLastColumn();
            base.OnColumnWidthChanged(e);
        }
    
        protected override void OnColumnWidthChanging(ColumnWidthChangingEventArgs e)
        {
            adjustLastColumn();
            base.OnColumnWidthChanging(e);
        }
    
        string GetExcelColumnName(int columnNumber)
        {
            int dividend = columnNumber;
            string columnName = String.Empty;
            int modulo;
    
            while (dividend > 0)
            {
                modulo = (dividend - 1) % 26;
                columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
                dividend = (int)((dividend - modulo) / 26);
            } 
    
            return columnName;
        }
    
        public Table Table
        {
            get {return new Table(table);}
            set
            {
                table = new Table(value);
    
                if (table != null)
                {
                    int columnCount = table.ColumnCount;
                    int rowCount = table.RowCount;
    
                    // one unnamed column for the row names (line numbers)
                    Columns.Add("");
    
                    for (int i=0; i<columnCount; i++)
                    {
                        Columns.Add(GetExcelColumnName(i+1));
                    }
    
                    // another empty column that will be filling the remaining client area
                    Columns.Add("");
    
                    for (int j=0; j<rowCount; j++)
                    {
                        ListViewItem lvi = new ListViewItem((j+1).ToString());
    
                        lvi.UseItemStyleForSubItems = false;                    
    
                        for (int i=0; i<columnCount; i++)
                        {
                            lvi.SubItems.Add(table[i,j]);
                        }
    
                        Items.Add(lvi);
                    }
    
                    AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
                    AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
    
                    adjustLastColumn();
                }
            }
        }
    }
    

    Table.cs:

    public class Table
    {
        string[,] data;
        string name = "";
        string info = "";
    
        public string Name
        {
            get {return name;}
            set {if (value != null) name = value; else name = "";}
        }
    
        public string Info
        {
            get {return info;}
            set {if (value != null) info = value; else info = "";}
        }
    
        public Table(string[,] originalData)
        {
            data = (string[,])(originalData.Clone());
        }
    
        public Table(Table originalData)
        {
            data = (string[,])(originalData.data.Clone());
            string name = originalData.Name;
            string info = originalData.Info;
        }
    
        public int RowCount {get{return data.GetLength(1);}}
    
        public int ColumnCount {get{return data.GetLength(0);}}
    
        public string this[int xIndex, int yIndex]
        {
            get
            {
                if (xIndex >= 0 && xIndex < data.GetLength(0) && yIndex >= 0 && yIndex < data.GetLength(1))
                    return data[xIndex, yIndex];
                else
                    return "";
            }
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   LarsTech    6 年前

    默认的drawtext实现似乎添加了不可移动的填充。改用textfrenderer类:

    // e.DrawText(TextFormatFlags.VerticalCenter | TextFormatFlags.SingleLine | 
    //            TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.WordEllipsis);
    TextRenderer.DrawText(e.Graphics, e.SubItem.Text, e.Item.Font, e.Bounds,
                          SystemColors.WindowText, SystemColors.Window,
                          TextFormatFlags.VerticalCenter | TextFormatFlags.WordEllipsis);