WPF系列教程——(一)仿TIM QQ界面

TIM QQ

我们先来看一下TIM QQ长什么样,整体可以将界面分为三个部分


TIM QQ

1. 准备

  • 阅读本文假设你已经有XAML布局的基础,所以只对部分布局进行说明。
  • 界面上的图标均来自 Material Design Icons
    选择需要的图标后点击View XAML
    图片.png

    会显示WPF的调用代码,直接复制到项目中即可,WPF是支持矢量图显示的。
    图片.png
  • 本文中的控件使用了开源的MaterialDesignInXamlToolkit,这是一款WPF的Material Design UI库,也是WPF最流行的UI库之一,可以轻松的做出漂亮的界面,到NuGet中搜索即可添加到项目。
    NuGet

    App.xaml文件中,添加以下代码,应用资源样式
    <SolidColorBrush x:Key="PrimaryHueMidBrush" Color="#1C93EC" /> Color表示所有控件的主题颜色,不添加的话所有控件颜色默认为紫色。
 <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <SolidColorBrush x:Key="PrimaryHueMidBrush" Color="#1C93EC" /> 
  </ResourceDictionary>

在需要使用MaterialDesignInXamlToolkit控件的页面引入命名空间
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"

  • 使用Grid布局将页面划分为三个区域,感觉Grid是万能布局,可以用它设计出大多数软件90%的界面
 <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="63*" />
            <RowDefinition Height="706*" />
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">

        </Grid>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="157*" />
                <ColumnDefinition Width="389*" />
            </Grid.ColumnDefinitions>
            <Grid Grid.Column="0">
                
            </Grid>
            <Grid Grid.Column="1">
                
            </Grid>
        </Grid>
 </Grid>
三个区域

2. 圆形头像

在WPF上显示圆形图片很简单,使用Ellipse绘制圆形设置宽和高一致绘制正圆,在内部使用Image笔刷填充图片,本文中的头像显示方式均以此来实现。

<Ellipse Width="50"
             Height="50">
                <Ellipse.Fill>
                   <ImageBrush  ImageSource="Images/github.png" />
                </Ellipse.Fill>
</Ellipse>

3. 工具栏设计

工具栏的三个不同几何图形,使用Polygon来绘制,再将内部填充不同的颜色,坐标自行测试选择适当位置。

工具栏

第一个多边形

<Polygon Points="0,0 700,0 756,65 0,65"
                             StrokeThickness="1">
                        <Polygon.Fill>
                            <SolidColorBrush Color="#1C93EC" />
                        </Polygon.Fill>
                    </Polygon>

第二个多边形

 <Polygon Points="700,0 780,0 740,50 "
                             StrokeThickness="1">
                        <Polygon.Fill>
                            <SolidColorBrush Color="#3E58C9" />
                        </Polygon.Fill>
                    </Polygon>

第三个多边形

 <Polygon Points="780,0 1100,0 1100,65 723,65 "
                             StrokeThickness="1">
                        <Polygon.Fill>
                            <SolidColorBrush Color="#3448A1" />
                        </Polygon.Fill>
                    </Polygon>

XAML代码如下,简书没有折叠代码功能啊,这段有点长。

  <materialDesign:ColorZone Mode="PrimaryMid"
                                      Name="NavBar"
                                      Height="65"
                                      MouseLeftButtonDown="NavBar_MouseLeftButtonDown"
                                      materialDesign:ShadowAssist.ShadowDepth="Depth3">

                <Grid>
                    <!--第三个几何图形-->
                    <Polygon Points="780,0 1100,0 1100,65 723,65 "
                             StrokeThickness="1">
                        <Polygon.Fill>
                            <SolidColorBrush Color="#3448A1" />
                        </Polygon.Fill>
                    </Polygon>
                    <!--第二个几何图形-->
                    <Polygon Points="700,0 780,0 740,50 "
                             StrokeThickness="1">
                        <Polygon.Fill>
                            <SolidColorBrush Color="#3E58C9" />
                        </Polygon.Fill>
                    </Polygon>
                    <!--第一个几何图形-->
                    <Polygon Points="0,0 700,0 756,65 0,65"
                             StrokeThickness="1">
                        <Polygon.Fill>
                            <SolidColorBrush Color="#1C93EC" />
                        </Polygon.Fill>
                    </Polygon>
                    <Ellipse Cursor="Hand"
                             HorizontalAlignment="Left"
                             Margin="10 5"
                             Width="50"
                             Height="50">
                        <Ellipse.Fill>
                            <ImageBrush  ImageSource="Images/github.png" />
                        </Ellipse.Fill>
                    </Ellipse>
                    <Grid HorizontalAlignment="Center"
                          Width="200">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <Grid Grid.Column="0">
                            <Button Width="60"
                                    Height="60"
                                    Background="{x:Null}"
                                    BorderBrush="{x:Null}"
                                    materialDesign:ShadowAssist.ShadowDepth="Depth1"
                                    Padding="0">
                                <Viewbox Width="30"
                                         Height="30">
                                    <Canvas Width="24"
                                            Height="24">
                                        <Path Data="M17,12V3A1,1 0 0,0 16,2H3A1,1 0 0,0 2,3V17L6,13H16A1,1 0 0,0 17,12M21,6H19V15H6V17A1,1 0 0,0 7,18H18L22,22V7A1,1 0 0,0 21,6Z"
                                              Fill="White" />
                                    </Canvas>
                                </Viewbox>
                            </Button>
                        </Grid>
                        <Grid Grid.Column="1">
                            <Button Width="60"
                                    Height="60"
                                    Background="{x:Null}"
                                    BorderBrush="{x:Null}"
                                    materialDesign:ShadowAssist.ShadowDepth="Depth1"
                                    Padding="0">
                                <Viewbox Width="30"
                                         Height="30">
                                    <Canvas Width="24"
                                            Height="24">
                                        <Path Data="M16.5,12A2.5,2.5 0 0,0 19,9.5A2.5,2.5 0 0,0 16.5,7A2.5,2.5 0 0,0 14,9.5A2.5,2.5 0 0,0 16.5,12M9,11A3,3 0 0,0 12,8A3,3 0 0,0 9,5A3,3 0 0,0 6,8A3,3 0 0,0 9,11M16.5,14C14.67,14 11,14.92 11,16.75V19H22V16.75C22,14.92 18.33,14 16.5,14M9,13C6.67,13 2,14.17 2,16.5V19H9V16.75C9,15.9 9.33,14.41 11.37,13.28C10.5,13.1 9.66,13 9,13Z"
                                              Fill="White" />
                                    </Canvas>
                                </Viewbox>
                            </Button>
                        </Grid>
                        <Grid Grid.Column="2">
                            <Button Width="60"
                                    Height="60"
                                    Background="{x:Null}"
                                    BorderBrush="{x:Null}"
                                    materialDesign:ShadowAssist.ShadowDepth="Depth1"
                                    Padding="0">
                                <Viewbox Width="30"
                                         Height="30">
                                    <Canvas Width="24"
                                            Height="24">
                                        <Path Data="M19,16A3,3 0 0,0 22,13A3,3 0 0,0 19,10H17.5V9.5A5.5,5.5 0 0,0 12,4C9.5,4 7.37,5.69 6.71,8H6A4,4 0 0,0 2,12A4,4 0 0,0 6,16V11H18V16H19M19.36,8.04C21.95,8.22 24,10.36 24,13A5,5 0 0,1 19,18H18V22H6V18A6,6 0 0,1 0,12C0,8.91 2.34,6.36 5.35,6.04C6.6,3.64 9.11,2 12,2C15.64,2 18.67,4.6 19.36,8.04M8,13V20H16V13H8M9,18H15V19H9V18M15,17H9V16H15V17M9,14H15V15H9V14Z"
                                              Fill="White" />
                                    </Canvas>
                                </Viewbox>
                            </Button>
                        </Grid>
                    </Grid>
                    <Grid HorizontalAlignment="Right"
                          Width="150">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <Grid Grid.Column="0">
                            <Button Height="60"
                                    Background="{x:Null}"
                                    BorderBrush="{x:Null}"
                                    materialDesign:ShadowAssist.ShadowDepth="Depth1"
                                    Padding="0">
                                <Viewbox Width="25"
                                         Height="25">
                                    <Canvas Width="24"
                                            Height="24">
                                        <Path Data="M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z"
                                              Fill="White" />
                                    </Canvas>
                                </Viewbox>
                            </Button>
                        </Grid>
                        <Grid Grid.Column="1">
                            <Button Height="60"
                                    Background="{x:Null}"
                                    BorderBrush="{x:Null}"
                                    materialDesign:ShadowAssist.ShadowDepth="Depth1"
                                    Padding="0">
                                <Viewbox Width="25"
                                         Height="25">
                                    <Canvas Width="24"
                                            Height="24">
                                        <Path Data="M20,14H4V10H20"
                                              Fill="White" />
                                    </Canvas>
                                </Viewbox>
                            </Button>
                        </Grid>
                        <Grid Grid.Column="2">
                            <Button Height="60"
                                    Background="{x:Null}"
                                    BorderBrush="{x:Null}"
                                    materialDesign:ShadowAssist.ShadowDepth="Depth1"
                                    Padding="0">
                                <Viewbox Width="25"
                                         Height="25">
                                    <Canvas Width="24"
                                            Height="24">
                                        <Path Data="M4,4H20V20H4V4M6,8V18H18V8H6Z"
                                              Fill="White" />
                                    </Canvas>
                                </Viewbox>
                            </Button>
                        </Grid>
                        <Grid Grid.Column="3">
                            <Button Height="60"
                                    Background="{x:Null}"
                                    BorderBrush="{x:Null}"
                                    materialDesign:ShadowAssist.ShadowDepth="Depth1"
                                    Padding="0">
                                <Viewbox Width="25"
                                         Height="25">
                                    <Canvas Width="24"
                                            Height="24">
                                        <Path Data="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
                                              Fill="White" />
                                    </Canvas>
                                </Viewbox>
                            </Button>
                        </Grid>
                    </Grid>

                </Grid>
            </materialDesign:ColorZone>

4. 好友列表设计

好友列表使用了ListView,效果图中的好友都是静态的数据,列表绑定会在下一节讲到。


好友列表
     <Grid Background="#FAFAFA"
                  Grid.Column="0">
                <ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                          Cursor="Hand">

                </ListView>
                <materialDesign:PopupBox Style="{StaticResource MaterialDesignMultiFloatingActionPopupBox}"
                                         PlacementMode="TopAndAlignCentres"
                                         ToolTipService.Placement="Left"
                                         ToolTip="TIM QQ"
                                         HorizontalAlignment="Right"
                                         VerticalAlignment="Bottom"
                                         Margin="20">

                </materialDesign:PopupBox>
            </Grid>

ListView中Item代码如下

 <ListViewItem Height="60"
                                  Padding="0">
                        <StackPanel Orientation="Horizontal"
                                    Margin="10 0">
                            <Ellipse Cursor="Hand"
                                     Width="50"
                                     Height="50">
                                <Ellipse.Fill>
                                    <ImageBrush  ImageSource="Images/head2.jpg" />
                                </Ellipse.Fill>
                            </Ellipse>
                            <StackPanel Orientation="Vertical"
                                        VerticalAlignment="Center"
                                        Margin="5 0">
                                <TextBlock FontSize="15"
                                           Foreground="Black"
                                           Text="糖宝" />
                                <TextBlock  Margin="0 2 0 0"
                                            FontSize="12"
                                            Text="Hello world" />
                            </StackPanel>
                        </StackPanel>
 </ListViewItem>

5. 名片设计

名片页面是不是和TIM QQ的几乎一模一样~


名片

XAML代码如下

<Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <Grid Grid.Row="0">
                            <Image  Stretch="UniformToFill" Source="Images/head1.jpg" />
                        </Grid>
                        <Grid Grid.Row="1">
                            <Button  Style="{StaticResource MaterialDesignFloatingActionButton}"
                                    HorizontalAlignment="Right"
                                    VerticalAlignment="Top"
                                    Margin="0 -30 5 0"
                                
                                    BorderBrush="{x:Null}"
                                    ToolTip="修改资料">
                                <materialDesign:PackIcon Kind="Pencil"
                                                         Height="24"
                                                         Width="24" />

                            </Button>

                            <StackPanel Orientation="Vertical">
                                <TextBlock Text="Go to hell!"
                                           HorizontalAlignment="Center"
                                           FontSize="35"
                                           Margin="0 20 0 0" />
                                <StackPanel Orientation="Horizontal"
                                            Margin="80 5 0 0 "
                                            
                                            >
                                    <TextBlock Text="账号  "
                                               Foreground="#B7B7B7" />
                                    <TextBlock Text="vaemc520@qq.com" />
                                </StackPanel>
                                <StackPanel Orientation="Horizontal"
                                            Margin="80 5 0 0 ">
                                    <TextBlock Text="昵称  "
                                               Foreground="#B7B7B7" />
                                    <TextBlock Text="Go to hell!" />
                                </StackPanel>
                                <StackPanel Orientation="Horizontal"
                                            Margin="80 5 0 0 ">
                                    <TextBlock Text="手机  "
                                               Foreground="#B7B7B7" />
                                    <TextBlock Text="183XXXXXXXX" />
                                </StackPanel>
                                <StackPanel Orientation="Horizontal"
                                            Margin="80 5 0 0 ">
                                    <TextBlock Text="邮箱  "
                                               Foreground="#B7B7B7" />
                                    <TextBlock Text="vaemc520@qq.com" />
                                </StackPanel>
                                <StackPanel Orientation="Horizontal"
                                            Margin="80 5 0 0 ">
                                    <TextBlock Text="职业  "
                                               Foreground="#B7B7B7" />
                                    <TextBlock Text="计算机/互联网/通信" />
                                </StackPanel>
                                <StackPanel Orientation="Horizontal"
                                            Margin="80 5 0 0 ">
                                    <TextBlock Text="空间  "
                                               Foreground="#B7B7B7" />
                                    <TextBlock Text="Go to hell! 的空间" />
                                </StackPanel>
                            </StackPanel>
 </Grid>

6. 最终效果

最终效果

欢迎Star https://github.com/vaemc/WpfTimQQ

7. 总结

接触到了WPF以后感觉用WinForm托控件真的好LOW,并且用WPF可以轻松的设计出好看的界面,以前经常写安卓也发现这俩玩意布局竟如此的雷同,然后就慢慢的过度到了WPF。
下一节将会以此项目为基础来讲诉WPF MVVM框架的实现,欢迎关注~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容