菜单

Silverlight项目中”自定义控件开发/Style”学习笔记

2019年3月15日 - mg娱乐场www4355com

本文不涉及高深的设计形式(比如mvc,mvvm之类),也绝非太多的编制程序技巧,只是记录本身做为asp.net开发者学习silverlight中自定义控件开发的有些进度,高手请绕过。 

先引进一篇不错的稿子http://www.cnblogs.com/carysun/articles/1259025.html 写得很完美,只可是图片讲解不够丰盛,初学者也许有点觉得跳跃性大了一些。 

正文发轫: 

做过asp.net网站开发的都知道用户控件是二个很方便的效应,常常大家会把部分模块化的效益封装成用户控件,用的时候一向拖出来即可,假诺用户控件很多,还是能设想把一部分逻辑成熟变化相对十分的小的控件单独从类型中拆分出来,以高达可选拔、可尊敬的“分层”(此分层非一般品种架构中的三层之意)

silverlight做为MS类别技术之一,自然也再而三了这一合计,允许开发者将常用的布局/功效/代码封装成自定义控件,须要的时候一向拖出来使用。 

看上面包车型地铁图:

图片 1

 那是一个独立的silverlight项目消除方案:

1.control是一个Silverlight类库,能够把品种中可采取的用户控件放在该项目中.(可以领略为UI层的撤并)

图片 2

2.silverlight是行业内部的Silverlight应用程序(或silverlight导航应用程序).(约等于UI层)

3.silverlight.web是用来测试silverlight项目标

本来,尽管还有一对常用的政工逻辑,也能够考虑再建三个silverlight类库(类似守旧支付中的BLL层)

接下去大家先新建贰个自定义控件(本文示例少将创设3个用户留言的自定义控件)

先调整一下暗中认可的命名空间(因为Control是Silverlight中的暗中同意控件类,为了防止命名空间与类名重复,提出最好换一个私下认可命名空间)

control项目上右击,选择”Properties”(属性)

图片 3

除去Control中暗许生成的Class1.cs,然后Add New
Item,选用”Silverlight模板化控件”,命名为”BBSComment.cs”

图片 4

能够看出,系统除创设了BBSComment.cs外,还创办了一个Themes/Generic.xaml(那些能够领略为web网站开发中的css,然则作用相对css更强有力)

图片 5 

图片 6public class BBSComment : Control
图片 7图片 8    图片 9{
图片 10        public BBSComment()
图片 11图片 12        图片 13{
图片 14            this.DefaultStyleKey = typeof(BBSComment);
图片 15        }
图片 16    }

 可以见到,BBSComment 继承自Control类,再来看下Generic.xaml

图片 17<ResourceDictionary
图片 18    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation
图片 19    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml
图片 20    xmlns:local=”clr-namespace:CustomControlDemo”>
图片 21
图片 22
图片 23    <Style TargetType=”local:BBSComment”>
图片 24        <Setter Property=”Template”>
图片 25            <Setter.Value>
图片 26                <ControlTemplate TargetType=”local:BBSComment”>
图片 27                    <Border Background=”{TemplateBinding Background}”
图片 28                            BorderBrush=”{TemplateBinding BorderBrush}”
图片 29                            BorderThickness=”{TemplateBinding BorderThickness}”>
图片 30                    </Border>
图片 31                </ControlTemplate>
图片 32            </Setter.Value>
图片 33        </Setter>
图片 34    </Style>
图片 35</ResourceDictionary>

 先不管其余,大家只看<ControlTemplate
>…</ControlTemplate>模板部分,这几个能够通晓为asp.net中的Repeater控件的ItemTemplate,即这些控件运行时,最后会把那边定义的内容体现出来(即一个Border边框) 

作者们来映证一下,先在silverlight项目中添加对Control项目标引用,在silverlight上右击,选取”Add
Reference”(添加引用),切换成Project标签,选用Control项目

图片 36 

开辟silverlight中的mainpage.xaml,起始入命名空间(假若不可能弹出下图中的选中项,请先重新编写翻译生成解决方案)

 

图片 37

然后就足以采纳刚才的自定义控件了,完整的mainpage.xaml应该象那几个样子

图片 38<UserControl x:Class=”Silverlight.MainPage”
图片 39    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” 
图片 40    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml
图片 41    xmlns:d=”http://schemas.microsoft.com/expression/blend/2008” xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006” 
图片 42   xmlns:custom=”clr-namespace:ControlLib;assembly=ControlLib”
图片 43    mc:Ignorable=”d” d:DesignWidth=”640″ d:DesignHeight=”480″>
图片 44  <Grid x:Name=”LayoutRoot”>
图片 45        <custom:BBSComment Width=”100″ Height=”100″ BorderThickness=”10″ Background=”AliceBlue” BorderBrush=”Red”></custom:BBSComment>
图片 46  </Grid>
图片 47</UserControl>

运行后,会看出一个金黄的border边框,表达Generic.xaml中定义的ControlTemplate确实起成效了

图片 48

tips:要是想体会asp.net开发中把控件”拖”到页面中的那种舒服,请切换来blend中处理(vs20第10中学也能够一向拖了,可是当下还只是beta版),MainPage.xaml上右击接纳”在Expression
Blend中打开” 

图片 49 

参考上海教室,找到Assets标签,选用Project,就能看出BBSComment这一个控件了,直接用鼠标按住拖到MainPage.xaml中来即可(爽吧,呵)

 

刚刚提到了Generic.xaml类似古板web开发中的css,既然是体制当然能够钦点不一致的外观了,大家修改一下那一个文件 

图片 50<ResourceDictionary
图片 51    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation
图片 52    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml
图片 53    xmlns:local=”clr-namespace:ControlLib”>
图片 54
图片 55    <Style TargetType=”local:BBSComment”>
图片 56        <Setter Property=”Template”>
图片 57            <Setter.Value>
图片 58                <ControlTemplate TargetType=”local:BBSComment”>
图片 59                    <Border Background=”{TemplateBinding Background}”
图片 60                            BorderBrush=”{TemplateBinding BorderBrush}”
图片 61                            BorderThickness=”{TemplateBinding BorderThickness}”>
图片 62                    </Border>
图片 63                </ControlTemplate>
图片 64            </Setter.Value>
图片 65        </Setter>
图片 66    </Style>
图片 67    
图片 68    <Style TargetType=”local:BBSComment” x:Name=”style2″>
图片 69        <Setter Property=”Template”>
图片 70            <Setter.Value>
图片 71                <ControlTemplate TargetType=”local:BBSComment”>
图片 72                    <Border Width=”100″ Height=”50″ Background=”Red” BorderBrush=”Green” BorderThickness=”3″>
图片 73                        
图片 74                    </Border>
图片 75                </ControlTemplate>
图片 76            </Setter.Value>
图片 77        </Setter>
图片 78    </Style>
图片 79</ResourceDictionary>

 那里本身把暗中同意生成的代码,复制了一节,并取名为style2,相当于样式表中定义了另三个类名,看下怎样选择,如故在Blend环境中,保持Silverlight项指标MainPage.xaml文件打开状态,注意左边面板中的Resources标签面板,在App.xaml上右击,接纳“Link
to Resource Ditionary”–>”Generic.xaml”

图片 80
这一步的成效也正是html中用<link
ref=”xxx.css”…/>引用样式,它会在app.xaml中发生如下变化:

图片 81<ResourceDictionary>
图片 82            <ResourceDictionary.MergedDictionaries>
图片 83                <ResourceDictionary Source=”/ControlLib;Component/Themes/Generic.xaml”/>
图片 84            </ResourceDictionary.MergedDictionaries>
图片 85</ResourceDictionary> 

即扩大了一节<ResourceDictionary>…</ResourceDictionary> 

引用了体制后,自然就能运用了,大家把刚才MainPage.xaml上的BBSComment控件删除掉(或屏蔽掉),再拖一个到页面上,并取名为bbsComment2,然后参考下图操作

图片 86

 实质上,这一操作会在控件上加码Style=”{StaticResource
style2}”那样一段,多么象html代码中的div
class=”style2″(某些技术真是一通百通)

<custom:BBSComment x:Name=”bbsComment2″ Style=”{StaticResource style2}” >

重复运维,效果如下:

图片 87 

明白了如何切换样式,再来谈谈怎么样编写style的题材,初学sl中的style,觉得语法很麻烦,相信大家也象笔者同一懒得去记,没提到,咱们能够用Blend解决(顺便说一下私家感受:blend
相对于 visual
studio,就好比web开发中的photoshop/fireworks相对于dreamweaver,前者用于做表面文章-UI部分,后者用于写后边的代码–html代码或c#代码,二者组合起来能够很有益的完结整个项目)
blend中双击Control项目中的Generic.xaml文件,会唤起:

图片 88
即能源文件无法在统一筹划视图下编写制定,要编制能源,请切换成能源面板

换来财富面板,展开Generic.xaml,会发现刚才定义的三个样式呈现于此,每一个后边还有三个编写制定按钮

图片 89

点击style2后的编辑按钮,会发觉右侧的Object And
Timeline面板有所扭转,在style上右击,参考下图操作

图片 90

ok,今后得以象编辑常规对象那样以“可视化”格局来编排“样式”了

 

接下去相比较一下html中的css与xaml中的style不等同的地点,我们精晓css中内联样式的优先级最高,会覆盖任何地点中的样式定义,即

<style type=”text/css”>
.demo{color:red}
</style>

<div class=”demo” style=”color:green”>sample</div>

这一段代码运维后,最后展现出来的文字颜色为原野绿,覆盖了原先的体裁定义

修改一下刚才mainpage.xaml中有关自定义控件的代码,如下:

<custom:BBSComment x:Name=”bbsComment2″ Style=”{StaticResource style2}” Background=”Blue” Width=”300″ Height=”50″ />

此地本身内定了可观,宽度,并设置了新的背景象,希望在运作时能有新的外观,不过运营后会发现,根本不起成效。

那正是xaml中的style跟html的css分歧的地点,sl中的style没有先行级别(只可以设置属性私下认可值),而且叁个门类中,借使有相同x:Name定义的体制,运维时会报错(即样式的称谓必须唯一)。

那么,如何让控件在运行时,可以便宜的决定外观呢?大家依然用最简便易行的图形界面来修改处理啊,再度请出Blend,在上一张图修改样式的界面中,比如咱们想让用户能在运维时动态控制宽度,没难点,选中border对象,在左侧的性质面板中找到Width设置栏,注意前面包车型地铁小白点,参考下图操作

图片 91

成就未来,阅览Generic.xaml中的变化 

<Border Width=”{TemplateBinding Width}”
Height=”50″ Background=”Red” BorderBrush=”Green”
BorderThickness=”3″></Border> 

在意浅莲红部分,那里成为了{TemplateBinding
Width},即运维时会动态绑定用户钦赐的增长幅度值,再度编写翻译运转,发现此时宽度已经起效果了(变宽了!)

图片 92

那里有一要注意,做了地点的处理后,倘使控件自个儿不写宽度,即:

<custom:BBSComment x:Name=”bbsComment2″ Style=”{StaticResource
style2}” />
运营时是啥也看不到的,没写宽度等同于宽度为0,为了修补那个毛病,再来修改下Generic.xaml这几个样式文件

图片 93<Style TargetType=”local:BBSComment” x:Name=”style2″>
图片 94    <Setter Property=”Width” Value=”500″ />
图片 95        <Setter Property=”Template”>
图片 96            <Setter.Value>
图片 97                <ControlTemplate TargetType=”local:BBSComment”>
图片 98                    <Border Width=”100″ Width=”{TemplateBinding Width}”  Background=”Red” BorderBrush=”Green” BorderThickness=”3″ />                             </ControlTemplate>
图片 99            </Setter.Value>
图片 100        </Setter>
图片 101    </Style>

在意新加的一行<Setter Property=”Width” Value=”500″
/>,那里评释那个控件的暗许宽度是500,假使不写宽度,则控件暗中同意宽度为500px

此间仅上课了Width宽度属性,至于其余性质,大家能够依葫芦画瓢,自身去品尝吧. 

除此以外“xaml中style”
比“html中css”强大的一个地点在于,css只好控制成分的外观,而style除了控制外观之外,还足以决定突显的内容。
比如说同样是刚刚的BBSComment控件,我们能够把generic.xaml中style2的概念改为: 

图片 102<Style TargetType=”local:BBSComment” x:Name=”style2″>
图片 103        <Setter Property=”Template”>
图片 104            <Setter.Value>
图片 105                <ControlTemplate TargetType=”local:BBSComment”>
图片 106                    <TextBlock Text=”TextBlock” TextWrapping=”Wrap”/>                   
图片 107                </ControlTemplate>
图片 108            </Setter.Value>
图片 109        </Setter>
图片 110    </Style>   

重复运营,发现刚才的Border已经没了,取而代之是单排文字”TextBlock”!换言之,style能够同时影响对象的外观和内容,在接下去的品味中,大家还将看到style的更强劲威力,它还是能够影响到目的的表现。

接下去看一下所谓的视觉状态(VisualState),我们抛开官方的概念,以web开发者的见解跟css来做一个类比,先看下这一个广阔的例子 

图片 111图片 112<style type=”text/css”>图片 113
图片 114
图片 115图片 116a:link{图片 117}{color:blue;text-decoration:none}
图片 118图片 119a:visited{图片 120}{color:black;text-decoration:none}
图片 121图片 122a:hover{图片 123}{color:red;text-decoration:underline}
图片 124图片 125a:active{图片 126}{color:green;text-decoration:none}
图片 127
图片 128图片 129.f12{图片 130}{font-size:12px;}
图片 131图片 132.f14{图片 133}{font-size:14px}
图片 134
图片 135</style>
图片 136
图片 137<a href=”#” class=”f12″>作者是1个链接(12号字)</a>
图片 138
图片 139<br/><br/>
图片 140
图片 141<a href=”#” class=”f14″>笔者是一个链接(14号字)</a>

对此a链接来讲,它也许会处于link,visited,hover,active这一组状态中的任何1个,此外对于同一个a标记的字体大小,也不容许同时处于三种大大小小状态(本示例中或然为12px,要么为14px,不容许便是12号字,又是14号字)

咱俩得以把”link,visited,hover,active”掌握为3个互斥状态组,当鼠标从四壁萧条地点活动到a链接上时,a链接从link(或visited)状态变为hover状态,点击时,又从hover状态变成active状态,但随便什么样,a成分只好同时处理这一种组状态中的某2个,类似:字体大小,区别的颜色…那么些也能够领悟为别的几组互斥的状态组。

没错,这实质上正是silverlight中的视觉状态组/视觉状态,直接用代码说话,修改generic.xaml的剧情为这么:

图片 142<ResourceDictionary
图片 143    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation
图片 144    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml
图片 145    xmlns:vsm=”clr-namespace:System.Windows;assembly=System.Windows”
图片 146    xmlns:local=”clr-namespace:ControlLib”>
图片 147
图片 148    <Style TargetType=”local:BBSComment”>
图片 149        <Setter Property=”Width” Value=”500″ />
图片 150        <Setter Property=”Height” Value=”200″ />
图片 151        <Setter Property=”Template”>
图片 152            <Setter.Value>
图片 153                <ControlTemplate TargetType=”local:BBSComment”>
图片 154                    <Border x:Name=”border” CornerRadius=”10″ Width=”{TemplateBinding Width}” Height=”{TemplateBinding Height}” Background=”#FFEFEFEF” BorderThickness=”10″ 
图片 155
图片 156BorderBrush=”#FFDCD7B6″>
图片 157
图片 158                        <vsm:VisualStateManager.VisualStateGroups>
图片 159                            
图片 160                            <vsm:VisualStateGroup x:Name=”CommState”>
图片 161                                
图片 162                                <vsm:VisualState x:Name=”normal”/>
图片 163                                <vsm:VisualState x:Name=”mouseover”>
图片 164                                    <Storyboard>
图片 165                                        <ColorAnimation Storyboard.TargetName=”border” Storyboard.TargetProperty=”(Border.BorderBrush).(SolidColorBrush.Color)” To=”Red” 
图片 166
图片 167Duration=”00:00:02″ />                                       </Storyboard>
图片 168                                </vsm:VisualState>
图片 169
图片 170                                <vsm:VisualStateGroup.Transitions>
图片 171                                    <vsm:VisualTransition From=”normal”  To=”mouseover” GeneratedDuration=”00:00:00.1″/>
图片 172                                    <vsm:VisualTransition From=”mouseover”  To=”normal” GeneratedDuration=”00:00:00.3″/>
图片 173                                </vsm:VisualStateGroup.Transitions>
图片 174
图片 175                            </vsm:VisualStateGroup>
图片 176                            
图片 177                        </vsm:VisualStateManager.VisualStateGroups>
图片 178
图片 179                        <StackPanel Orientation=”Vertical”>
图片 180                            <TextBox x:Name=”txtContent” Text=”走过路过,不要失去” TextWrapping=”Wrap” Height=”145″ BorderThickness=”0″/>
图片 181                            <StackPanel>
图片 182                                <Button Content=”宣布评论” x:Name=”btnSubmit” Height=”25″ Width=”80″ Margin=”5,5,0,0″ HorizontalAlignment=”Left”/>
图片 183                                <TextBlock x:Name=”txtTip” Text=”评论内容不得跨越200字,请听从互联网相关法律法规” Visibility=”Collapsed”></TextBlock>
图片 184                            </StackPanel>
图片 185                        </StackPanel>
图片 186                    </Border>
图片 187                </ControlTemplate>
图片 188            </Setter.Value>
图片 189        </Setter>
图片 190    </Style>
图片 191</ResourceDictionary>

解释一下:

<vsm:VisualStateGroup x:Name=”CommState”>…
</vsm:VisualStateGroup>那里定义三个气象组CommState,

<vsm:VisualState x:Name=”normal”/>,<vsm:VisualState
x:Name=”mouseover”>…</vsm:VisualState>定义三个视觉状态,而mouseover里面包车型地铁Storyboard把边框的水彩改为深蓝(即一对一于前方提到的a:hover效果),

<vsm:VisualStateGroup.Transitions>
          <vsm:VisualTransition From=”normal”  To=”mouseover” GeneratedDuration=”00:00:00.1″/>
          <vsm:VisualTransition From=”mouseover”  To=”normal” GeneratedDuration=”00:00:00.3″/>
</vsm:VisualStateGroup.Transitions>

这一段定义了从normal状态变化到mouseover状态的过渡时间,好了,代码看懂了,运转一下你会遗憾的发现,鼠标移动到控件上时,并不曾按你预期的相当边框变红?换言之,状态并未发生变化(也称迁移),那也是跟css分裂的地点,css中a的伪类由浏览器自动监听鼠标动作进行切换,而在xaml的style中,对于自定义控件,必须手写代码进行切换

修改一下BBSComment.cs代码: 

图片 192using System.Windows;
图片 193using System.Windows.Controls;
图片 194using System.Windows.Input;
图片 195
图片 196namespace ControlLib
图片 197图片 198图片 199{
图片 200    public class BBSComment : Control
图片 201图片 202    图片 203{
图片 204        public BBSComment()
图片 205图片 206        图片 207{
图片 208            this.DefaultStyleKey = typeof(BBSComment);
图片 209
图片 210            this.MouseEnter += new MouseEventHandler(BBSComment_MouseEnter);
图片 211            this.MouseLeave += new MouseEventHandler(BBSComment_MouseLeave);
图片 212
图片 213            VisualStateManager.GoToState(this as Control, “normal”, false);
图片 214
图片 215        }
图片 216
图片 217        void BBSComment_MouseLeave(object sender, MouseEventArgs e)
图片 218图片 219        图片 220{
图片 221            VisualStateManager.GoToState(sender as Control, “normal”, true);
图片 222        }
图片 223
图片 224        void BBSComment_MouseEnter(object sender, MouseEventArgs e)
图片 225图片 226        图片 227{
图片 228
图片 229            VisualStateManager.GoToState(sender as Control, “mouseover”, false);
图片 230        }
图片 231    }
图片 232}

 那里我们定义了三个事件,并用VisualStateManager.GoToState()方法手动对事态举办了切换,再运维一下,有反馈了!

图片 233

顺手提一句:视觉状态的概念,除了手动写代码,在blend中也足以轻松化解

图片 234

最后来一下小扩大:那几个示例中BBSComment的剧情完全被style定死了,要是我们期望在运作时能扩大学一年级下剧情,比如加3个验证码的输入框之类,能或不能够象 

图片 235<custom:BBSComment>
图片 236    <custom:BBSComment.Content>
图片 237        <!–//图片 238概念本身的情节–>
图片 239    </custom:BBSComment.Content>
图片 240</custom:BBSComment>

如此这般来定义呢?当然可以,但是要求做一些修改,我们把public class
BBSComment : Control 改成 public class
BBSComment : ContentControl,即让BBSComment继承自ContentControl

下一场MainPage.xaml中写类似上面的代码,编写翻译就能经过了,不过假诺急着想看下效果,抱歉,还百般!

图片 241<custom:BBSComment x:Name=”bbs3″ Margin=”0,10,0,0″>
图片 242            <custom:BBSComment.Content>
图片 243                <StackPanel Orientation=”Horizontal”>
图片 244                    <TextBlock Text=”验证码:” Height=”20″ Margin=”5,5,0,0″ TextAlignment=”Center” VerticalAlignment=”Center”/>
图片 245                    <TextBox Height=”20″ Width=”40″  Margin=”0,5,0,0″></TextBox>
图片 246                    <TextBlock Text=”1680″ Height=”20″ Margin=”5,5,0,0″ VerticalAlignment=”Center” HorizontalAlignment=”Center”/>
图片 247                </StackPanel>
图片 248            </custom:BBSComment.Content>
图片 249        </custom:BBSComment>

继续修改Generic.xaml,参考上边包车型大巴代码:

 <StackPanel Orientation=”Vertical”>
                            <TextBox x:Name=”txtContent” Text=”走过路过,不要错过” TextWrapping=”Wrap” Height=”145″ BorderThickness=”0″/>
                            <StackPanel Orientation=”Horizontal”>
                                <ContentPresenter></ContentPresenter>
                                <Button Content=”公布评论” x:Name=”btnSubmit” Height=”25″ Width=”80″ Margin=”5,5,0,0″ HorizontalAlignment=”Left”/>
                                <TextBlock x:Name=”txtTip” Text=”评论内容不得超越200字,请遵从互连网相关法律法规” Visibility=”Collapsed” HorizontalAlignment=”Center” 

VerticalAlignment=”Center” Margin=”5,0,0,0″ ></TextBlock>
                            </StackPanel>
                        </StackPanel>

其间扩大了三个<ContentPresenter></ContentPresenter>,目的在于保留三个占位符,能够让用户通过<xxx.Content>….</xxx.Content>来扩充内容,运转时扩充的情节将替换那几个占位符(回看一下Dreamweaver中的模板页,Asp.Net中的母版页MasterPage,多么类似的宏图!)

自然,自定义控件也援救事件,例如:

<custom:BBSComment x:Name=”bbs2″ Margin=”0,10,0,0″ MouseLeftButtonUp=”bbs2_MouseLeftButtonUp”></custom:BBSComment>

图片 250 private void bbs2_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
图片 251图片 252        图片 253{
图片 254            HtmlPage.Window.Alert(“you clicked me”);
图片 255        }

百川归海写完了,希望对初学者有所帮忙,可能有人会问:自定义控件为什么直接新建2个”Silverlight用户控件”(如下图),那里面想怎么编辑就怎么编辑,不是更有利?

图片 256

实在如此,不过“存在即创立”,既然MS把Silverlight模板化控件单独分出来,自然有它的道理,我们逐步体会呢。

后记:文中所记内容纯属个人通晓,不当或错误之处,欢迎指正,转发请注脚出处(菩提树下的杨过)

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图