【问题标题】:Enable Scrollbar on Parent Form在父窗体上启用滚动条
【发布时间】:2013-08-01 21:26:26
【问题描述】:

我有以下问题。基于图像 子窗体上的某些控件无法正确显示。我也不能在子窗体上使用Autoscroll set to true,因为它的一些控件是anchored bottom。 我想的解决方法是当子窗体的高度重叠时在父窗体上有一个滚动条。我应该在我的代码中添加什么以使父表单具有滚动条?

我使用此代码在父表单中显示子表单。

void ParentButtonClickNew(){

  ChildForm entry = new ChildForm();
  LoadChildForm(entry, this); 
}



 public void LoadChildForm(object childForm, object container)
    {
        System.Windows.Forms.Form xForm = (System.Windows.Forms.Form)childForm;
        System.Windows.Forms.Control control = (System.Windows.Forms.Control)container;

        xForm.TopLevel = false;

        if (control.Controls.Count == 0)
        {
            xForm.Parent = control;
            xForm.StartPosition = FormStartPosition.CenterScreen;
            //xForm.WindowState = System.Windows.Forms.FormWindowState.Maximized;
            xForm.Show();
            xForm.BringToFront();

        }
        else
        {
            bool isFound = false;
            for (int i = 0; i <= control.Controls.Count - 1; i++)
            {
                try
                {
                    System.Windows.Forms.Form myForm = (System.Windows.Forms.Form)control.Controls[i];
                    if (myForm.Name == xForm.Name)
                    {
                        isFound = true;
                        xForm.StartPosition = FormStartPosition.CenterScreen;
                        myForm.Show();
                        myForm.BringToFront();
                    }
                    else
                    {
                        myForm.SendToBack();
                    }
                }
                catch { }
            }
            if (!isFound)
            {
                try
                {
                    xForm.Parent = control;
                    System.Windows.Forms.Form myForm = (System.Windows.Forms.Form)control.Controls[xForm.Name];
                    xForm.StartPosition = FormStartPosition.CenterScreen;
                    myForm.Show();
                    myForm.BringToFront();
                }
                catch { }
            }
        }
    }

【问题讨论】:

  • control.AutoScroll = true; 怎么样,你必须将父表单的AutoScroll 设置为true。
  • 不,控件没有那个属性
  • 你必须将container 转换为ContainerControlFormControl 没有AutoScroll
  • 我试过了,还是不行。
  • 嘿@KingKing 我再次测试了它。仅当父窗体的控件未设置为锚定底部且父窗体较高时,父窗体上的 AutoScroll 才会显示。我希望它像 mdiform 一样工作,但只是垂直滚动条..

标签: c# .net winforms scrollbar


【解决方案1】:

这段代码中有一些非常严重的错误,正在下雨 nullref 和 cast 异常。你真的需要停止使用 try/catch 隐藏这些错误。这是您提出这个问题的核心原因,您只是无法弄清楚代码内部发生了什么。

您遇到问题的最大原因是您设计方法的方式。您必须始终创建一个表单实例并将其作为第一个参数传递。麻烦的是,如果表单已经存在,那么您永远不会真正使用该实例。因此,尝试在该实例上设置 AutoScroll = true 之类的属性没有任何效果。

你需要一些完全不同的东西。就像 Type 参数一样。可能是这样的:

    public void LoadChildForm(Type childForm, Control container) {
        foreach (Control child in container.Controls) {
            if (child.GetType() == childForm) {
                // Found it, bring to front
                child.BringToFront();
                return;
            }
        }
        // Doesn't exist yet, create a new instance
        Form xForm = (Form)Activator.CreateInstance(childForm);
        xForm.TopLevel = false;
        xForm.Visible = true;
        container.Controls.Add(xForm);
        xForm.BringToFront();
        // Show scrollbar
        xForm.AutoScrollMinSize = new Size(0, 2000);
    }
}

请注意,当您正确设计代码时,代码会变得多么清晰易懂。你可以这样称呼它:

void ParentButtonClickNew(){
    LoadChildForm(typeof(ChildForm), this); 
}

请注意真正的问题,这绝不会是 MDI 的模拟。它看起来像一个 MDI 子窗体,但事实并非如此。你不能激活窗口,标题栏总是有“未激活”的颜色。如果您确实想要具有滚动条的 MDI 客户端窗口,那么您必须创建一个额外的容器窗口,Panel 就可以了。使用 AutoScroll = true。

然而,结果永远不会像 MDI 并且不会很有用。考虑将停靠窗口布局作为 MDI 的替代方案。好样的在维芬罗的DockPanel Suite

【讨论】:

  • 感谢韩先生。感谢您提供的信息并纠正我的错误。我尝试了以下解决方案,效果更好。如何为表单添加最大化状态?我添加了 xForm.WindowState 设置为最大化,但我遇到了 ui 问题。
  • 这是我警告过的,它不再是 形式了。您需要隐藏损坏的标题栏,将 FormBorderStyle 属性设置为 None。你不会想这样做,但你应该这样做。
  • 有没有办法不将 FormBorderStyle 设置为 none?
  • 韩先生。只是想问。我不知道该怎么办。如果我有这样的代码Childform entry = new Childform(); entry.TransactionId = 1; LoadChildForm(entry,this);,我该如何传递一个值?
  • 这不会去任何地方。如果您不想接受我的建议并使用像 DockPanel Suite 这样的现有库,那么强烈考虑只使用 Winforms 中内置的普通 MDI 支持。您可以稍后再改进,将其搁置,直到您获得更多经验。
【解决方案2】:

所以您将子表单放在父表单上,其中子表单大于父表单。我要告诉你的第一件事是你不应该创建一个比父窗体更大的子窗体。它总是很复杂。其次,我会推荐一些比滚动条更简单的东西。您可以在子窗体上注册鼠标按下和鼠标向上的事件并执行以下操作:

  private Point p;

  private void Form1_MouseDown(object sender, MouseEventArgs e)
  {
     p = new Point(e.X, e.Y);
  }

  private void Form1_MouseUp(object sender, MouseEventArgs e)
  {
     int distance = e.Y - p.Y;

     // so the window won't move with every click
     if (distance > 10)
     {
        Location = new Point(Location.X, Location.Y + distance);
     }
  }

它比滚动条更容易,对用户来说更方便

【讨论】:

    【解决方案3】:

    为什么不尝试将所有子窗体控件放在面板内并在面板内放置滚动条,我认为这样会容易得多

    【讨论】:

      猜你喜欢
      • 2012-04-18
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 2013-08-11
      • 2011-05-18
      • 1970-01-01
      相关资源
      最近更新 更多