自定义布局控件
讲到自定义布局控件我们必须得先谈一下在WPF中自定义控件在WPF自定义控件你可以选择下图的一些基类作为继承对象你也可以继承自已有的一些控件这个就看你的需要了。其实开发WPF自定义控件和开发WinForm、ASP.NET自定义控件基本类似只是要注意一些特别的地方比如依赖属性的处理、路由事件、视觉树和逻辑树等等。于今天只是讲如何开发一个自定义的Panel所以在清楚了基类的前提下首先得了解它有哪些属性和事件这样就可以确定哪些是不需要单独写、哪些是需要override。下图就是Panel和基类FrameworkElement 的类图在清楚了上面这张图以后我们就可以着手开始写了我们知道布局系统的工作原理是先测量后排列测量就是确定面板需要多大空间排列则是定义其面板内子元素的排列规则。自定义面板要继承自Panel类并重写MeasureOverride和rrangeOverride方法即可如下便是一个简单的自定义Panel:namespace WPFLayoutDemo { public class PlotPanel : Panel { public PlotPanel() : base() { } //重写默认的Measure方法 protected override Size MeasureOverride(Size availableSize) { Size panelDesiredSize new Size(); foreach (UIElement child in InternalChildren) { child.Measure(availableSize); panelDesiredSize child.DesiredSize; } return panelDesiredSize; } //重写默认的Arrange方法 protected override Size ArrangeOverride(Size finalSize) { foreach (UIElement child in InternalChildren) { double x 50; double y 50; child.Arrange(new Rect(new Point(x, y), child.DesiredSize)); } return finalSize; } } }控件的最终大小和位置是由该控件和父控件共同完成的,父控件会先给子控件提供可用空间availableSize,子控件再反馈给父控件一个自己的期望值DesiredSize,父控件最后根据自己所拥有的空间大小与子控件的期望值分配一定的空间给子控件并返回自己的大小.那么这个过程就是通过MeasureOverride 和ArrangeOverride这两个方法来完成注意父控件的availableSize是减去Margin、padding等的值。本来想自己开发一个较复杂的Panel控件放上来但一搜网络发现已经有很多很好的Panel控件所以在这里我也不写那么多了大家可以研究一下这些控件我也研究了几个觉得最好理解且最美观的当属“FishEyePanel FanPanel, Paul Tallett, codeproject ”,大家可以根据链接过去看一下Paul Tallett讲解得非常的细致。TreeMapPanel, Kevin Moore (see bag-o-tricks for code)AnimatingTilePanel, Kevin Moore (see bag-o-tricks for code)Disposing Virtualizing Stack Panel, Aaron, WiredPrairie.usTimeLinePanel, Rob Zelt, robzelt.com (with credit to Robert Ingebretsen and Lauren Lavoie)Chart and Lens Panel by John Stewien (code available?)DiagonalPanelFishEyePanel FanPanel, Paul Tallett, codeprojectRadiaPanel ItemsRadialPanel, Rhett log (Henry Hahn posted a Radial panel in 2005, but Im not sure if it runs or not?)DisclaimerPanel, ChazSpanningStackPanel, Nick TheusenPlotPanel, Windows SDK SampleCollapsiblePanel, Thomas LebrunCornerStacker, Nick ThuesenStickyPanel, Unni, Blend PMItemSkimmingPanel, Pavan Podila顺便也链接两幅图讲到这里我们也顺便提一下写WPF自定义控件的几个步骤以后在讲到这一节的时候会详细讲解首先你得清楚你的自定义控件是干什么用的能解决什么问题公用到什么程度其他项目也可以用、本项目用、项目当中一个模块用、只有一个地方用是继承已有的控件还是从头写对设计时是否支持样式和模板的定义等。确定好了上面的步骤后我们就可以建立项目的结构类和资源文件等该放在什么位置也就在这一步确定。选择要继承的基类UIElement、FrameworkElement 、Control 、ContentControl 、HeaderedContentControl 、ItemsControl 、Selector 、RangeBase还是已有的一些控件。重写默认的样式和新建一些样式并附默认值。由于WPF的属性基本都是依赖属性所以我们也要新建一些依赖属性。逻辑树和视觉树的一些处理以及事件等。十五.本文总结今天我们主要讲了WPF布局系统对整个布局系统的原理、各个Panel的基本用法分别用XAML和C#两种方式实现同一个功能便于大家学习以及自定义布局控件做了一些介绍由于内容太多我只是力所能及的做一些相关的介绍和演示所以只能给大家提供一个参考如果大家想了解更多还需要去看专门的教材同时有些知识也只是个人的一些见解所以大家只能将就着看了。写篇文章也是怀着技术交流的心态发布出来由于是自己对这些技术的使用总结和心得体会错误之处在所难免所以希望大家能够多多指点这样也能纠正我的错误观点以便和各位共同提高最后如果大家感兴趣可以关注WPF 基础到企业应用系列索引这个系列文章我也会不定期的逐渐更新谢谢各位的关注也欢迎和各位交流讨论。