http://blog.csdn.net/beilinu/article/details/8009968
之前做了一个类似于360界面的WPF程序,主要是通过对基本控件的模版来修改实现的,在其中定义了很多模版,后来由于源码丢失,导致在制作相同风格的程序时又得重头开始,所以尝试了下自定义控件的制作,制作一套构成界面的基本控件,方便以后调用。
界面样式:
首先分析下界面构成:主要是由一个无边框窗体+TAB控件+若干个系统按钮构成,在wpf中,窗体控件的继承比较麻烦,加上无边框窗体样式设置比较简单,所以只需要制作一个TAB控件和系统按钮控件就可以了。按钮也只需一个就够了,样式都是一样的,只要更改下图片就行了。
好了,开始动手吧,首先是TAB控件
1.启动vs,创建名为“WMTabControl”的wpf自定义控件项目,并继承TabControl,vs为我们生成了2个文件:Generic.xaml,WMTabControl.cs其中Generic.xaml是用来定义控件样式模版的,WMTabControl.cs可以用来实现各种功能,比如新添加的属性之类的。
由于我们的WMTabControl不需要添加额外属性及功能,只是外观的改变,所以WMTabControl.cs就不用管他了,默认就行。
接着在Generic.xaml里面定义控件样式模版
- <Grid>
- <DockPanel HorizontalAlignment="Stretch" Height="Auto" LastChildFill="True" Margin="0" Grid.Row="0" VerticalAlignment="Stretch" Width="Auto" Grid.RowSpan="1">
- <StackPanel x:Name="HeaderPanel" Height="Auto" VerticalAlignment="Top" Width="Auto" DockPanel.Dock="Top" IsItemsHost="True" Orientation="Horizontal" CanHorizontallyScroll="True"/>
- <Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Width="Auto" DockPanel.Dock="Bottom" Margin="0" Background="{TemplateBinding Background}">
- <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Height="Auto"/>
- </Border>
- </DockPanel>
- </Grid>
然后继续新建项目WMTabItem
添加模版
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="{x:Type local:WMTabItem}">
- <Grid x:Name="templateRoot" SnapsToDevicePixels="True" Width="74" Height="82">
- <VisualStateManager.VisualStateGroups>
- <VisualStateGroup x:Name="CommonStates"/>
- <VisualStateGroup x:Name="SelectionStates"/>
- <VisualStateGroup x:Name="FocusStates"/>
- <VisualStateGroup x:Name="ValidationStates"/>
- </VisualStateManager.VisualStateGroups>
- <Grid.RowDefinitions>
- <RowDefinition Height="62"/>
- <RowDefinition Height="20"/>
- </Grid.RowDefinitions>
- <Border x:Name="mainBorder" BorderThickness="1,1,1,0" Margin="0" Grid.RowSpan="1" Background="{TemplateBinding Background}" Width="48" Height="48" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5"/>
- <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Focusable="False" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Top" TextElement.Foreground="{TemplateBinding Foreground}"/>
- </Grid>
- <ControlTemplate.Triggers>
- <Trigger Property="Selector.IsSelected" Value="True">
- <Setter Property="Background" TargetName="templateRoot">
- <Setter.Value>
- <ImageBrush Stretch="Uniform" ImageSource="/WMControl;component/image/toolbar_pushed.png"/>
- </Setter.Value>
- </Setter>
- </Trigger>
- <MultiTrigger>
- <MultiTrigger.Conditions>
- <Condition Property="IsMouseOver" Value="True"/>
- <Condition Property="Selector.IsSelected" Value="False"/>
- </MultiTrigger.Conditions>
- <Setter Property="Background" TargetName="templateRoot">
- <Setter.Value>
- <ImageBrush ImageSource="/WMControl;component/image/toolbar_hover.png"/>
- </Setter.Value>
- </Setter>
- <Setter Property="RenderTransform" TargetName="mainBorder">
- <Setter.Value>
- <TransformGroup>
- <ScaleTransform ScaleX="1.05" ScaleY="1.05"/>
- <SkewTransform/>
- <RotateTransform/>
- <TranslateTransform/>
- </TransformGroup>
- </Setter.Value>
- </Setter>
- </MultiTrigger>
- </ControlTemplate.Triggers>
- </ControlTemplate>
- </Setter.Value>
好了,一个控件搞定了,下面开始制作按钮控件,老样子,添加新项目WMButton。
按钮有三个状态,默认,按下,鼠标划过,在这里主要是通过触发器改变背景色实现。
另外还要新添加两个属性,分别用来存放 鼠标按下,鼠标划过的图片。
- public ImageSource MoverBrush
- {
- get { return base.GetValue(MoverBrushProperty) as ImageSource; }
- set { base.SetValue(MoverBrushProperty, value); }
- }
- public static readonly DependencyProperty MoverBrushProperty = DependencyProperty.Register("MoverBrush", typeof(ImageSource), typeof(WMButton));
- public ImageSource EnterBrush
- {
- get { return base.GetValue(EnterBrushProperty) as ImageSource; }
- set { base.SetValue(EnterBrushProperty, value); }
- }
- public static readonly DependencyProperty EnterBrushProperty = DependencyProperty.Register("EnterBrush", typeof(ImageSource), typeof(WMButton));
接着在模版里面定义两个笔刷,并绑定到上面两个属性
- <ImageBrush x:Key="EnterBrush" ImageSource="{Binding EnterBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:WMButton}}}" Stretch="None"></ImageBrush>
- <ImageBrush x:Key="MoverBrush" ImageSource="{Binding MoverBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:WMButton}}}" Stretch="None"></ImageBrush>
- <ControlTemplate.Triggers>
- <Trigger Property="IsMouseOver" Value="True">
- <Setter Property="Background" TargetName="border" Value="{StaticResource MoverBrush}"/>
- </Trigger>
- <Trigger Property="IsPressed" Value="True">
- <Setter Property="Background" TargetName="border" Value="{StaticResource EnterBrush}"/>
- </Trigger>
- </ControlTemplate.Triggers>
到此为止,两个控件就搞定了。下面开始试试看,
1.重新建立WPF项目,并制作一个无边框窗体
2.引用刚才制作的控件,把TAB控件放在窗体上,并删除自带的TabItem(因为我们有自定义的TabItem,不用他的),在tab控件根目录下添加刚才制作的WMTabItem。
好难看。。。。。不过不要着急,给他换个图片先
额,效果还不错,好了,多复制几个,再把刚才制作的按钮也放上,再添加三张图片,默认状态的图片就直接改变背景笔刷就行了,另外两个状态就要用到刚才添加的两个新属性了,在属性面板找到刚才添加的新属性,分别添加两张图片。
还行,继续拖控件,关闭,最大化,最小化,图片自己找就行了
好了,一个基本的界面就搭建好了,可以加上标题之类的,位置也可以根据需要调整下。很方便,只需要将刚才制作的两个控件拖进来,改变下图片,一个简单的界面布局就完成了。
添加换肤功能:
主要是绑定窗体背景,具体就不多说了,看代码