65.9K
CodeProject 正在变化。 阅读更多。
Home

为您的应用程序添加自定义对话框

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.46/5 (8投票s)

2005年10月16日

2分钟阅读

viewsIcon

80441

downloadIcon

1040

本文介绍了一个基础对话框窗体类,可用于创建各种 OK/取消 类型的对话框。 它还给出了自定义控件创建和窗体继承的基础知识。

Sample Image - CustomDialogs.png

引言

对话框是应用最广泛的 UI 窗口类型之一。 几乎无法想象没有对话框的 Windows 应用程序。 其中一些很简单,例如带有几个按钮的消息框。 它们的功能几乎被 .NET MessageBox 类所涵盖。 有些更复杂,例如文件保存/加载对话框或打印机设置。 这些也有它们对应的 .NET 类。 但是,如果我们需要的对话框类型没有被 MessageBox 或标准对话框控件涵盖,该怎么办? 在实际应用中,对自定义对话框的需求经常出现。 当然,这只是在窗体上放置必要的控件、添加确定和取消按钮而已,就大功告成了! 但是为什么要一遍又一遍地做同样的工作呢? 让我们制作基础对话框类并通过继承来重用它。 这不正是 OOP 的全部内容吗?

BaseDialog 类

首先,让我们问问自己,我们希望基础对话框有什么。

首先,我们需要它有确定和取消按钮。 让我们把它们放在窗体的左下方。

其次,让我们画一条线将它们与窗体的其余部分分隔开。 哎呀,.NET 中没有线条控件。 没关系,我们将自己制作这个控件,并在过程中学习自定义控件创建的基础知识。

第三,我们需要在继承窗体调整大小时更新这些控件的布局。

protected override void OnLoad(EventArgs e) {
  base.OnLoad (e);
  OnResize(e);
}
 
protected override void OnResize(EventArgs e) {
  base.OnResize (e);
  Line1.Location = new Point(6, this.Size.Height - 64);
  Line1.Size = new Size(this.Size.Width - 18, 2);
  int okx = this.Size.Width - cbOk.Size.Width - 14;
  if(cbCancel.Visible && this.Visible)
    okx -= cbCancel.Size.Width + 4;
  cbOk.Location = new Point(okx, this.Size.Height - cbOk.Size.Height - 32);
  cbCancel.Location = new Point(this.Size.Width - 
           cbCancel.Size.Width - 14, 
           this.Size.Height - cbCancel.Size.Height - 32);
}

最后,也是最重要的一点。 继承者应该能够在对话框完成时添加一些自定义操作,无论是使用 DialogResult.Ok 还是 DialogResult.Cancel。 这些可能是一些验证操作,并能够阻止对话框完成。 带有布尔返回值的 protected virtual 方法将很好地服务于此目的。

private void cbOk_Click(object sender, System.EventArgs e) {
  ExitOk();
}

private void cbCancel_Click(object sender, System.EventArgs e) {
  ExitCancel();
}

protected void ExitOk() { 
  if(cbOk.Enabled==true) {
    if(OnOk()) {
      this.DialogResult = DialogResult.OK;
      this.Close();
    }
  }
}

protected void ExitCancel() {
  if(cbCancel.Enabled==true) {
    if(OnCancel()) {
      this.DialogResult = DialogResult.Cancel;
      this.Close();
    }
  }
}

protected virtual bool OnOk() {
  return true;
}

protected virtual bool OnCancel() {
  return true;
}

线条控件

这很简单,就像 1-2-3 一样。

  1. System.Windows.Forms.Control 继承。
  2. 自己绘制它。
    protected override void OnPaint(PaintEventArgs e) {
      base.OnPaint(e);
      Redraw(e.Graphics);
    }
  3. 在调整大小时重新绘制它。
    protected override void OnResize(EventArgs e) {
      base.OnResize(e);
      // height shouldn't change, only length changes
      this.Height = 6;
      Redraw(this.CreateGraphics());
    }

这是绘画

private void Redraw(Graphics g) {
  // drawing dark edge of line
  Pen pen = new Pen(SystemColors.ControlDark, 1);
  Point p1 = new Point(1, 2);
  Point p2 = new Point(this.Width - 2, 2);
  g.DrawLine(pen, p1, p2);
  // drawing bright edge of line
  pen = new Pen(SystemColors.ControlLightLight, 1);
  p1 = new Point(1, 3);
  p2 = new Point(this.Width - 2, 3);
  g.DrawLine(pen, p1, p2);
  p1 = new Point(this.Width - 2, 2);
  g.DrawLine(pen, p1, p2);
}

如何使用

现在创建对话框变得很愉快。 将继承的窗体添加到您的项目中(选择 BaseDialog 进行继承)。 添加必要的控件和代码。 不要忘记充分利用添加控件的 Anchor 属性。 将窗体调整为首选大小。 如果需要,覆盖 OnOkOnCancel 方法以添加验证代码。

将调用代码添加到应用程序窗体。 例如

private void button1_Click(object sender, System.EventArgs e) {
  SampleDialog sd = new SampleDialog();
  if(sd.ShowDialog()==DialogResult.OK) {
    // ...
  }
}

现在是一些练习

  • 尝试制作一个没有取消按钮的对话框。
  • 尝试制作一个是/否对话框。
  • 尝试隐藏一条线,并在一个组框中放置您的控件。

所有这些都可以在不更改 BaseDialog 的情况下完成。

历史

  • 2005 年 10 月 16 日 - 文章提交。
© . All rights reserved.