其中一个 频繁请求的MFC功能 (顺便说一句,感谢您的反馈,并不断更新!)是在运行时智能地调整对话框及其内容大小的能力。
一种方法是拦截 WMU大小 并相应地重新计算子控件的大小和位置。它可以工作,但极易出错– 想象一下对应用程序中每个对话框中的每个控件都这样做。它还将在应用程序的表示层中引入非平凡的逻辑,这会给以后的维护带来麻烦。
在VisualStudio2015RC中,我们引入了一种一致的方法来管理运行时对话框的布局—我们称之为动态对话框布局。
让我们从一个示例开始,说明此功能的用途。想象一个只有一个按钮的对话框(别担心,我很快就会看到更现实的例子):
如果我们使此对话框的大小可调,用户将能够拉伸窗口,结果如下:
这一点用都没有。为了使调整大小有意义,我们需要为按钮找到一个更好的位置,也许还需要调整它的大小。一个简单而明智的方法是让按钮“粘”到对话框的右下角。换句话说,就像父窗口一样 调整大小 通过 十 对话框单位水平和 Y 垂直单位,我们希望按钮 移动 向右和向下移动相同的量。
让我们继续实施这个。在资源编辑器中打开“属性”窗口,然后单击对话框中的“确定”按钮。您将看到一个名为“动态布局”的新属性集:
现在将“Moving Type”更改为“Both”,并将“Moving X”和“Moving Y”设置为100(记住,我们希望按钮在主机对话框调整大小时同时向右和向下移动):
我们现在还不打算改变“尺码类型”——我马上就来。
现在保存并重新编译。运行应用程序并拉伸对话框。瞧:
那可有用多了,不是吗?
让我们更现实一点,再添加一个按钮“取消”:
我们现在需要决定在调整主机对话框的大小时按钮的行为。最简单的方法是让“确定”按钮贴在左下角,让“取消”按钮贴在右下角。我们将“确定”的动态布局设置为“移动类型=垂直”,“移动Y=100”。“Cancel”按钮将具有“Vertical,100,100”(就像上一个示例中的“OK”按钮一样)。
保存、编译、运行和调整大小:
不错吧?
现在,让我们试验一下“size Type”属性。在我的下一个示例中,我希望按钮按对话框的大小成比例缩放。我们将在这里做一些数学计算,所以为了使它更简单,我创建了一个大小为200的新对话框×100个对话单元。每个按钮的宽度设置为80个单位(在本例中,高度无关紧要)。
我希望按钮随着对话框的增长和收缩,始终保持原来的比例,即80/200或40%的对话框宽度。另外,我想在每个按钮和对话框边缘之间保持恒定的空间,我们称之为Δ:
如何使用动态布局设置来表示?
让我们从“确定”按钮开始。就其移动而言,它将继续垂直移动100%,因此它仍固定在底部边缘。我还希望它动态调整主机对话框的大小。按钮占据了对话框宽度的40%,这意味着每次父对话框的宽度增加100个单位,我希望“确定”按钮增加40个单位。以下是如何使用动态布局属性来表示它:
“取消”按钮需要更多的工作。随着父对话框的增长,此按钮将同时水平和垂直移动。垂直移动是很容易的-我想按钮粘到底部边缘,所以这是100%。接下来,我将从“OK”按钮复制“Sizing X”属性–这两个按钮应该保持相同的增长率,这样无论主机对话框的大小,它们的大小总是相同的。
现在,我们来计算“移动X”属性。我说了我们在这里做些数学,所以开始吧。当对话框的宽度从200到300增加100个单位时,每个单位的宽度相应增加,80*300/200= 120.“取消”按钮原来的X位置是200-Δ-80 = 120- Δ. 对话框宽度增加100个单位后,“取消”按钮的新X位置将为300-Δ-120 = 180- Δ.
到目前为止和我在一起?很好。正如我们刚刚确定的,“取消”按钮的位置从120-Δ 至180-Δ, i、 增加60个单位。这就是我们的答案——X位置的增长是对话框宽度增长的60%。
还有其他方法可以计算,有时您需要一张餐巾或一个信封的背面(特别是对于多个控件作为一个组的复杂布局)。我开发的一个有用的心智模型是这样的:“如果对话框的宽度(高度)增加了100个单位,那么我应该增加或移动多少控件?”
以下是“取消”按钮的全套动态布局属性:
这是我们调整了大小的对话框,非常漂亮:
诚然,调整按钮的大小并不是很有趣——它确实让鼠标更容易点击,但仅此而已。调整大小对于包含非平凡内容的控件非常有用,例如列表框、树控件等。
为了使其更加有用,我将在对话框中添加一个列表框:
我保持按钮属性不变。列表框将随主机对话框水平和垂直增长,并保持附着在左上角(即不移动):
下面是调整大小的对话框:
我在这里描述的所有功能当然都是通过编程实现的——动态对话框布局API已经添加到MFC中。此外,尤其是如果您不是鼠标点击式的开发人员,您可以直接在RC文件中编辑动态对话框布局属性。当然,我们会在MSDN上记录这一点,为了简短起见,我不会在这里描述这一点。
一如既往,我们对你的评论很感兴趣。这个特性仍然有点粗糙,所以您的及时反馈将允许我们解决RTM版本中的任何遗漏。
本文使用的示例应用程序附在下面。