当前位置: 首页 > article >正文

C#里使用PerformLayout,强制控件将布局逻辑应用于其所有子控件。

前几天,使用DataGridView来进行动态数据显示,但是发现右边的滚动条会显示不正确。
比如设置显示第100行了,但是滚动条的位置还是在最顶端,
如果你去点击一下滚动条,它又立即更新,并且跳到正确的位置显示。

一开始认为界面没有更新,找了Refresh()函数,又调用窗口更新函数,
最后还使用下面代码反向映射获取滚动条:
ScrollBar vsbar = (ScrollBar)typeof(DataGridView).GetProperty("VerticalScrollBar", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).GetValue(datagridview1, null);
并设置对应的位置,但是还是没有正确地显示。

到这个时候,已经找了一天半时间了,又去翻MSDN的文档,又去百度,还去bing。
但是还没有解决。

最后发现了一个函数PerformLayout(),它是立即强制界面刷新,并且进行重新设置。
后来通过调用这个函数,就可以解决滚动更新位置不正确的问题了。

例子如下:

using System.Windows.Forms;
using System.Drawing;

public class LayoutForm :
    System.Windows.Forms.Form

{
    public LayoutForm() : base()
    {
        InitializeComponent();
    }

    internal System.Windows.Forms.Button Button1;
    internal System.Windows.Forms.Button Button2;
    internal LayoutControl LayoutControl1;
    internal System.Windows.Forms.Button Button3;

    private void InitializeComponent()
    {
        this.Button1 = new System.Windows.Forms.Button();
        this.Button2 = new System.Windows.Forms.Button();
        this.Button3 = new System.Windows.Forms.Button();
        this.LayoutControl1 = new LayoutControl();
        this.SuspendLayout();
        this.Button1.Location = new System.Drawing.Point(16, 16);
        this.Button1.Name = "Button1";
        this.Button1.Size = new System.Drawing.Size(120, 32);
        this.Button1.TabIndex = 0;
        this.Button1.Text = "Center textbox on control";
        this.Button2.Location = new System.Drawing.Point(152, 16);
        this.Button2.Name = "Button2";
        this.Button2.Size = new System.Drawing.Size(104, 32);
        this.Button2.TabIndex = 3;
        this.Button2.Text = "Shrink user control";
        this.Button3.Location = new System.Drawing.Point(96, 232);
        this.Button3.Name = "Button3";
        this.Button3.TabIndex = 5;
        this.Button3.Text = "Reset";
        this.LayoutControl1.BackColor = System.Drawing.SystemColors.ControlDark;
        this.LayoutControl1.Location = new System.Drawing.Point(72, 64);
        this.LayoutControl1.Name = "LayoutControl1";
        this.LayoutControl1.Size = new System.Drawing.Size(150, 160);
        this.LayoutControl1.TabIndex = 6;
        this.ClientSize = new System.Drawing.Size(292, 266);
        this.Controls.Add(this.Button3);
        this.Controls.Add(this.Button2);
        this.Controls.Add(this.Button1);
        this.Controls.Add(this.LayoutControl1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);
        this.Button1.Click += new System.EventHandler(Button1_Click);
        this.Button2.Click += new System.EventHandler(Button2_Click);
        this.Button3.Click += new System.EventHandler(Button3_Click);
    }

    [System.STAThread]
    public static void Main()
    {
        Application.Run(new LayoutForm());
    }

    // This method explicitly calls raises the layout event on 
    // LayoutControl1, changing the Bounds property.
    private void Button1_Click(System.Object sender, System.EventArgs e)
    {
        LayoutControl1.PerformLayout(LayoutControl1, "Bounds");
    }

    // This resize of LayoutControl1 implicitly triggers the layout event. 
    //  Changing the size of the control affects its Bounds property.
    private void Button2_Click(System.Object sender, System.EventArgs e)
    {
        LayoutControl1.Size = new System.Drawing.Size(100, 100);
    }

    // This method explicitly calls PerformLayout with no parameters, 
    // which raises the Layout event with the LayoutEventArgs properties
    // equal to Nothing.
    private void Button3_Click(System.Object sender, System.EventArgs e)
    {
        LayoutControl1.PerformLayout();
    }
}

// This custom control has the Layout event implented so that when 
// PerformLayout(AffectedControl, AffectedProperty) is called 
// on the control, where AffectedProperty equals "Bounds" the 
// textbox is centered on the control.
public class LayoutControl :
    System.Windows.Forms.UserControl
{
    internal System.Windows.Forms.TextBox TextBox1;

    public LayoutControl() : base()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        this.TextBox1 = new System.Windows.Forms.TextBox();
        this.SuspendLayout();
        this.TextBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
        this.TextBox1.Name = "TextBox1";
        this.TextBox1.TabIndex = 0;
        this.BackColor = System.Drawing.SystemColors.ControlDark;
        this.Controls.Add(this.TextBox1);
        this.Name = "LayoutControl";
        this.ResumeLayout(false);
        this.Layout += new LayoutEventHandler(LayoutControl_Layout);
    }

    // This method is called when the Layout event is fired. 
    // This happens by during the initial load, by calling PerformLayout
    // or by resizing, adding or removing controls or other actions that 
    // affect how the control is laid out. This method checks the 
    // value of e.AffectedProperty and changes the look of the 
    // control accordingly. 
    private void LayoutControl_Layout(object sender,
        System.Windows.Forms.LayoutEventArgs e)
    {
        if (e.AffectedProperty != null)
        {
            if (e.AffectedProperty.Equals("Bounds"))
            {
                TextBox1.Left = (this.Width - TextBox1.Width) / 2;
                TextBox1.Top = (this.Height - TextBox1.Height) / 2;
            }
        }
        else
        {
            this.Size = new System.Drawing.Size(150, 160);
            TextBox1.Location = new System.Drawing.Point(16, 24);
        }
        TextBox1.Text = "Left = " + TextBox1.Left + " Top = " + TextBox1.Top;
    }
}


http://www.kler.cn/news/357207.html

相关文章:

  • pandas-使用技巧
  • 用Aconvert.com将MOBI文件转换为PDF:一步步指南
  • Mysql中表字段VARCHAR(N)类型及长度的解释
  • void关键字
  • ubuntu 20.04 网卡启用后,只有ipv6 没有 ipv4 无法上网
  • Linux_c 有名管道练习
  • Facebook Marketplace为什么无法使用的原因?
  • 树莓派刷入OpenWrt后扩容overlay的方法
  • 诺贝尔物理学奖与机器学习、神经网络:一场跨时代的融合与展望
  • Spring容器详解:BeanFactory和ApplicationContext的不同
  • spring mvc后端实现过程
  • 【计算机网络 - 基础问题】每日 3 题(四十一)
  • 字节回应实习生破坏大模型训练:确有此事 但部分报道夸大失实
  • 推荐系统 # 二、推荐系统召回:协同过滤 ItemCF/UserCF、离散特征处理、双塔模型、自监督学习、多路召回、曝光过滤
  • VUE 仿神州租车-开放平台
  • Java中的一些名词概念
  • C++服务端的配置文件库介绍
  • Linux 中文件的权限说明
  • 论线段树的调试
  • 如何保护您的服务器免受Shellshock Bash漏洞的影响