silverlight   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

http://www.cnblogs.com/yayx/archive/2008/04/23/1167110.html 看见园子里有兄弟在讨论到关于WPF/SL中的属性的问题,比如: “为啥flex可以直接对控件的left,top这些属性直接操作,sl还要转一下。这个很难理解,难道是因为dp的好用?相对dp的使用flex的实现简单明了的多了” 正好我最近在研究WPF,在这儿说说我的看法。可能大家大

http://www.cnblogs.com/yayx/archive/2008/04/23/1167110.html

看见园子里有兄弟在讨论到关于WPF/SL中的属性的问题,比如:

“为啥flex可以直接对控件的left,top这些属性直接操作,sl还要转一下。这个很难理解,难道是因为dp的好用?相对dp的使用flex的实现简单明了的多了”

正好我最近在研究WPF,在这儿说说我的看法。可能大家大多就是在用WPF或者SL就是做界面,因此首先比较关心界面布局的问题,我就先以WPF的layout为例解释一些用法

WPF中的布局对象

WPF中不可以给每个界面元素控件都加上"Left"或者"Top"这样的属性吗?其实不是,在一般的布局时,WPF为每个继承自FrameworkElement的组件提供了Margin这个属性,通过这个属性,我们可以轻松的设置四周的边距。再加上HorizontalAlignment和VerticalAlignment属性,我们足以完成一般的元素定位。最常用的,我们在Windows中随便一个Button,就会看到生成类似这样的XAML代码:

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

< Button  Name ="button1"   Margin ="0,28,7"  HorizontalAlignment ="Right"  Width ="53" > button </ Button >

使用Margin属性,渲染时的控件具体位置是如何决定的?我们可以说是“控件自己决定的”,或者说是“WPF统一决定的”。

除此之外,WPF还提供了另一种布局方式,也就是利用布局对象进行布局,这种布局方式最大的特点是,由父控件统一对子对象的布局进行管理。这样的控件有"Border"(单个子控件),"StackPanel"(流布局),"DockPanel"(停靠布局等),还有最常用的"Gird"。相信大家用这些布局控件已经很熟悉了。我们来看一些示例代码,看看WPF是怎样实现"由父控件统一对子对象的布局进行管理"的。以Canvas作为例子

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

class  Canvas:Panel

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

{

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
//定义DependencyProperty

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
//public static readonly DependencyProperty LeftProperty = 

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?


WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
//public static readonly DependencyProperty TopProperty = 

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

 

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?


WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
protected override Size MeasureOverride(Size availableSizE)

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
{

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        
//这里计算所有子控件自身的期望尺寸大小

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        foreach (UIElement ele in InternalChildren)

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        
{

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

            ele.Measure(availableSizE);

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        }
            

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

         
//这里返回自己(父控件)的测量大小,可用多大就多返回多大,并没有根据子控件变化

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        return availableSize;

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    }

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
protected override Size arrangeOverride(Size finalSizE)

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
{

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        
//这里计算每个子控件的位置,也就是对子控件进行布局

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        foreach (UIElement ele in InternalChildren)

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        
{

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

            
//这个Rect用来指定子控件相对自己的位置

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

            rect itsRect = new rect(

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

                
new Point((double)ele.GetValue(LeftProperty), (double)ele.GetValue(TopProperty)), //*这句是关键

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

                ele.DesiredSize,

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

                ele.DesiredSize

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

                );

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

            ele.Arrange(itsRect);

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        }
     

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        
return finalSize

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    }

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

}
 

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?


WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

详细的布局过程可以参一些书籍(强烈推荐很经典的《Application = Code + Markup:WPF程序设计指南》),这里不多说,注意ArrangeOverride方法中的new Point((doublE)ele.GetValue(LeftProperty),(doublE)ele.GetValue(TopProperty)),这一句使用GetValue方法获得了每个子控件的Left和Top属性,然后据此对子控件进行定位。

我不熟悉Flex,就和以前其他布局方式对比一下,比如Winform,Winform时代有个老大帮我们布局。老大说了,我们每个能参与布局的对象都有Left,Top,或者还有Position来指定Relative还是Absolute这样(我确实想到css去了),现在不一样了,因为“权力下放”,WPF把布局的权利直接下放给了布局控件,这就麻烦了,Canvas需要的是Left属性,Top属性,Grid可能需要Row属性,column属性,DockPanel可能需要Dock属性,那怎么办呢?于是我们就使用Attached Property,把属性定义在各个“小老大”下面,下面参与布局的“小兄弟”就使用Attached Property的方式来设置和读取这些属性的值。

也许你问这种“权力下放”有什么好处,如果你从WPF自带的一些布局控件还体会不到好处的话,我推荐一个链接大家可以看看各式各样的炫酷的自定义Layout:

Why WPF Rocks (Custom Layout Panel Showcase)

其实,如果你坚定的想为每个“小兄弟”建立一个Left和Top的话,你完全可以自己实现类似如下的代码

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

class  MyFrameworkElement : FrameworkElement

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

{

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
public int Left { get; }

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
public int Top { get; }

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
//

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?


WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

}
 

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?


WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

class  MyCanvas : Canvas

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

{

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
protected override Size arrangeOverride(Size finalSizE)

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    
{

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        
foreach (UIElement ele in InternalChildren)

@H_607_613@

        
{

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

            MyFrameworkElement mele 
= ele as MyFrameworkElement;

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

            
if (mele != null)

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

            
{

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

                rect itsRect 
= new rect(

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

                    
new Point(mele.Left, mele.Top),

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

                    ele.DesiredSize,

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

                    ele.DesiredSize

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

                    );

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

                ele.Arrange(itsRect);

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

            }

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        }

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

        
return base.ArrangeOverride(finalSizE);

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

    }

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

}
 

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?


WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?

不知你感觉如何,反正我不喜欢这样的实现。MyFrameworkElement和MyCanvas被强耦合在一起了,我不知道DockPanel控件是否还需要Left和Top属性,但是这两个属性确实存在,难道我需要定义MyFrameworkElementForCanvas,MyFrameworkElementForDockPanel...?太恐怖了

不过插一句,WPF中并没有所谓的特定的“布局对象”,其实每一个视觉对象(Visual)都可以为自己的子对象(们)安排布局。

形成模式

抛开布局不谈,从设计模式和面向对象的设计来说,这种设置属性值的方式可以算一种很有意义的模式,他很漂亮的分离了属性(Left),拥有属性的对象(Element),定义属性的对象(Canvas),属性值四者之间的耦合关系。DependencyProperty和AttachedProperty不仅在layout system中有很大的用处,在数据绑定,动画支持,资源,风格等都有很好的应用。

当然,任何复杂的设计都是有代价的,这种方式最大的代价也许是性能然在值得存储上WPF进行了很多优化(可以参我的另一篇即将发布的Post),但性能损失肯定存在。另一方面,复杂的设计必定会增加用户(我们程序员)使用的复杂度,也就是我们必须使用GetValue或者是SETVALue方法获取值了。不过在使用复杂度上面,WPF进行了一些官方的规范处理,他希望普通的DependencyProperty都能被封装成名为"CLR Wapper"的get/set方法,AttachedProperty封装成类似Canvas.SetLeft(v,150) 这样的语法,于是,便出现了Canvas.SetLeft()这样的方法。。

另外Silverlight本身还只是Beta版本,所以最好别拿Silverlight说事儿。呵呵,我还是很喜欢WPF。

总结

这一篇Post首先从WPF的布局系统说起,介绍了布局系统中是如何应用AttachedProperty的,然后总结的阐述了为什么会出现Canvas.SetLeft()这样的语法。 以上是我个人的一些看法,如果有什么不对希望大家多多指正~

大佬总结

以上是大佬教程为你收集整理的WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?全部内容,希望文章能够帮你解决WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。