网格与画布

时间:2009-07-02 18:18:39

标签: .net wpf xaml grid canvas

我正在寻找在WPF中使用Canvas vs. Grid面板的意见。 我需要制作基本上有网格布局的经典输入表单,有些可能在内部有小数据网格,组框,但都在网格布局中对齐。我正在努力为我的所有表单使用Grid或Canvas面板。网格给了我很好的结构;我可以更容易地保持控制的对齐。我将为所有窗口提供基类(继承Window类),因此Visual Studio中的设计器将无用,因为它存在这种继承的问题,并且使用Grid面板我甚至不需要设计器,我可以设置窗口SizeToContent所以一切都很合适。但是再次使用Canvas,我能够以任何我喜欢的方式定位控件,这只是我在使用Canvas时看到的好处。

我没有那么多的WPF经验来预测我可以从客户的布局请求中得到什么样的问题。在网络表单上,我有时会使用表单的绝对定位,以防万一客户有一些“特殊”的请求,无论是控制像素是在右上还是左上等等。每个人都与要求苛刻的客户合作,知道我的意思。

我想看看你的想法,在商业申请表格布局建设中有什么利弊?为什么一个比另一个好?任何一个面板不好用的情况,有的不是吗?一个面板到另一个面板的缺点是什么?你会用什么面板?

由于

5 个答案:

答案 0 :(得分:16)

Canvas主要用于自定义绘图功能,而不是其他任何东西。网格绝对是自定义布局的最佳选择。

答案 1 :(得分:3)

您可以深入了解网格的实际布局,列/行跨度,宽度,高度等。

在我看来,通过控制行和列sizez比在硬编码到画布中的所有内容更容易在网格上进行各种项目的布局。如果他们决定稍后改变决议,它也会使事情变得更容易。

来自Adam Nathan的 WPF Unleashed (p.168):

  

使用网格模仿画布   如果您使用单个行和列保留Grid并设置Horizo​​ntalAlignment和   VerticalAlignment将所有子项与Stretch以外的值相关联,将子项添加到   单个单元就像一个Canvas。将Horizo​​ntalAlignment设置为Left和   VerticalAlignment to Top就像将Canvas.Left和Canvas.Top设置为0.设置   Horizo​​ntalAlignment to Right和VerticalAlignment to Bottom就像设置一样   Canvas.Right和Canvas.Bottom为0.此外,将Margin值应用于每个   element可以为您提供与将Canvas的附加属性设置为相同的效果   值。

您还可以使用网格中控件的内容进行创作,以获得更精细的布局控制。

画布对于类似对话框的东西很有用,它很少会改变大小,并且只有一些控件,因为随着数字的增长将它们全部放出会花费很多时间。

我个人自己使用网格。将内容放到像素级别可能需要更多的工作,但是在5%的时间内,有必要抽象出很多麻烦。当需要动态调整行和列的大小时,它也很好,GridSplitter使它成为一个快照。

答案 2 :(得分:2)

绝对网格似乎是您需要的。

我会将网格比作html中的表格(在适当使用时非常有用),而Canvas更像是一个div。不同之处在于,网格应该是HTML中的表格,而div和vs Canvas也是如此。

关于网格主题,花时间定义RowDefinitions和ColumnDefinitions,而不是在控件上放置margin以正确定位所有内容。如果你不这样做,你会后悔的。

答案 3 :(得分:0)

即使您无法使用VS Designer,您仍然可以使用XAML可视化设计器来创建/编辑网格内容。

WPF / SL / XAML的主要用户体验优势之一是类似HTML的“流动”布局功能。即使你现在的设计可能不需要它,但它显然是未来,非常值得学习如何精细化。

查看Rob Relyea的优秀可用列表XAML editors

答案 4 :(得分:0)

我会使用Grid或专门的Grid子类。你是对的是View继承。 UWP中的Visual Studio设计器,WPF使用相同的方法名称为基础和子类生成支持代码。它不编译。

由于我对仿制药进行了预先处理,因此我们可以回到之前的方法论。其中一个是辅助类。每个视图都实现IBaseView,并具有属性ViewHelperViewHelper<T>。可能需要enum ViewHelperOptions。如果需要,每个ViewHelper都可以使用继承而不会破坏Visual Designer。这允许使用通用代码以及特定的视图代码,而不会破坏MVVM模型。让我们将其称为MVHVM,因为ViewHelper了解ViewHelper。这进一步将V与VM分开。

完整的实施可能需要使用Activator.CreateInstance。另一个考虑因素是设计者调用的构造函数。您必须将所有“will-crash-if-not-running”代码移动到(例如)Loaded事件中生成的Initialization中。或者,您可以使用(UWP):

if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled)
{ DoStuffWhichShouldOnlyBeDoneAtRunTime(); }