WPF仿网易云音乐系列(二、歌单创建窗口+登录设置模块)
老衲牺牲午休时间写博客,都快把自己感动了,-_-!!
之前上一篇随笔,我看了下评论,有部分人说WPF已经凉凉了,这个我觉得,这只是一个达到自己目的的工具而已,只要自己能用这个工具,得心应手的做出自己想要的东西就行,关心工具本身凉了没,个人觉得没啥意义;另外,我一个做Java的都没泼凉水,你.Net自己的东西,你们还不满意了,太过分了,haha;
以上,瞎bb一通,轻喷...下面开始正题;
一.简介
上一篇文章,咱们利用Expander+RadioButton实现了左侧菜单栏(或者是导航栏),这一片随笔,做创建歌单窗口和登录设置按钮那一坨...咱们先来看看原版长啥样子
看上去蛮厉害的样子,咱们开始搞一搞;
二.正文
创建歌单窗口
首先需要创建一个窗口。。然后设置WindowStyle="None" 使窗口无边框化;另外,窗口在弹出的时候,是有一个蒙版效果的;这里咱们还需要给他加上蒙版;话不多说,上代码;
窗体xmal
1 <Window x:Class="CloudMusic.CreateAlbum" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:CloudMusic" 7 mc:Ignorable="d" 8 Foreground="#444" 9 Closed="CreateAlbumWindow_Closed" 10 ShowInTaskbar="False" 11 WindowStyle="None" 12 WindowStartupLocation="CenterOwner" 13 Title="CreateAlbum" Height="250" Width="430"> 14 <Window.Resources> 15 <!--文本操作右键菜单--> 16 <ContextMenu x:Key="TextBoxContextMenu" > 17 <MenuItem Command="ApplicationCommands.Cut" /> 18 <MenuItem Command="ApplicationCommands.Copy" /> 19 <MenuItem Command="ApplicationCommands.Paste" /> 20 <MenuItem Command="ApplicationCommands.SelectAll" /> 21 </ContextMenu> 22 </Window.Resources> 23 <Grid> 24 <Grid.RowDefinitions> 25 <RowDefinition Height="45"/> 26 <RowDefinition Height="*"/> 27 </Grid.RowDefinitions> 28 <StackPanel Grid.Row="0"> 29 <TextBlock Text="新建歌单" FontSize="18" Margin="10"/> 30 <Border BorderBrush="#A7A7A7" BorderThickness="0.3"/> 31 </StackPanel> 32 <StackPanel Grid.Row="1"> 33 <TextBox Name="CreateAlbumTitle" Grid.Row="0" Tag="20" Margin="20" Height="40" TextChanged="CreateAlbumTitle_TextChanged" FontSize="14"> 34 <TextBox.Style> 35 <Style TargetType="TextBox"> 36 <Setter Property="ContextMenu" Value="{DynamicResource TextBoxContextMenu}" /> 37 <Setter Property="Template"> 38 <Setter.Value> 39 <ControlTemplate TargetType="{x:Type TextBox}"> 40 <Border x:Name="border" Width="Auto" Height="Auto" BorderThickness="1" BorderBrush="#A7A7A7"> 41 <Grid x:Name="grid" Background="#FFFFFF"> 42 <ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" HorizontalAlignment="Left"/> 43 <TextBlock x:Name="x" Visibility="Collapsed" Foreground="#A7A7A7" Text="歌单标题" 44 VerticalAlignment="Center" HorizontalAlignment="Left" FontFamily="Microsoft YaHei"/> 45 <TextBlock Margin="5,0" x:Name="x1" Foreground="#A7A7A7" Text="{TemplateBinding Tag}" 46 VerticalAlignment="Center" HorizontalAlignment="Right" FontFamily="Microsoft YaHei"/> 47 </Grid> 48 </Border> 49 <ControlTemplate.Triggers> 50 <Trigger Property="Text" Value="{x:Null}"> 51 <Setter Property="Visibility" TargetName="x" Value="Visible"></Setter> 52 </Trigger> 53 <Trigger Property="Text" Value=""> 54 <Setter Property="Visibility" TargetName="x" Value="Visible"></Setter> 55 </Trigger> 56 </ControlTemplate.Triggers> 57 </ControlTemplate> 58 </Setter.Value> 59 </Setter> 60 <Style.Triggers> 61 62 <Trigger Property="IsMouseOver" Value="True"> 63 <Setter Property="Background" Value="Transparent"/> 64 <Setter Property="Foreground" Value="#444"/> 65 </Trigger> 66 <Trigger Property="IsFocused" Value="True"> 67 <Setter Property="Background" Value="Transparent"/> 68 <Setter Property="Foreground" Value="#444"/> 69 </Trigger> 70 <Trigger Property="IsEnabled" Value="False"> 71 <Setter Property="Background" Value="Transparent"/> 72 <Setter Property="Foreground" Value="#444"/> 73 </Trigger> 74 </Style.Triggers> 75 </Style> 76 </TextBox.Style> 77 </TextBox> 78 <CheckBox Margin="20,20" Foreground="#A7A7A7"> 79 设置为隐私歌单 80 </CheckBox> 81 <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="20,10"> 82 <Button Style="{StaticResource ColorButton}" Width="100" Height="35" FontSize="16" 83 Click="Button_Click_1"> 84 新建 85 </Button> 86 <Button Style="{StaticResource ColorButton}" Margin="20,0,0,0" Width="100" 87 Height="35" FontSize="16" Click="Button_Click" 88 Background="White" Foreground="{StaticResource MainColor}">取消</Button> 89 </StackPanel> 90 </StackPanel> 91 </Grid> 92 </Window>
cs代码:
1 /// <summary> 2 /// CreateAlbum.xaml 的交互逻辑 3 /// </summary> 4 public partial class CreateAlbum : Window 5 { 6 public CreateAlbum() 7 { 8 InitializeComponent(); 9 } 10 11 public static void ShowDialog(Window owner) 12 { 13 //蒙板 14 Grid layer = new Grid() { Background = new SolidColorBrush(Colors.White),Opacity=0.4 }; 15 //父级窗体原来的内容 16 UIElement original = owner.Content as UIElement; 17 owner.Content = null; 18 //容器Grid 19 Grid container = new Grid(); 20 container.Children.Add(original);//放入原来的内容 21 container.Children.Add(layer);//在上面放一层蒙板 22 //将装有原来内容和蒙板的容器赋给父级窗体 23 owner.Content = container; 24 25 CreateAlbum ca = new CreateAlbum() { Owner = owner }; 26 ca.ShowDialog(); 27 } 28 29 private void CreateAlbumWindow_Closed(object sender, EventArgs e) 30 { 31 //容器Grid 32 Grid grid = this.Owner.Content as Grid; 33 //父级窗体原来的内容 34 UIElement original = VisualTreeHelper.GetChild(grid, 0) as UIElement; 35 //将父级窗体原来的内容在容器Grid中移除 36 grid.Children.Remove(original); 37 //赋给父级窗体 38 this.Owner.Content = original; 39 } 40 41 private void Button_Click(object sender, RoutedEventArgs e) 42 { 43 44 this.Close(); 45 46 } 47 /// <summary> 48 /// 添加歌单 49 /// </summary> 50 /// <param name="sender"></param> 51 /// <param name="e"></param> 52 private void Button_Click_1(object sender, RoutedEventArgs e) 53 { 54 if (CreateAlbumTitle.Text.Length > 20 || CreateAlbumTitle.Text.Length <= 0) return; 55 CommonEvent._CreateAlbum(CreateAlbumTitle.Text); 56 this.Close(); 57 } 58 59 private void CreateAlbumTitle_TextChanged(object sender, TextChangedEventArgs e) 60 { 61 CreateAlbumTitle.Tag = (20 - CreateAlbumTitle.Text.Length).ToString(); 62 } 63 }
ColorButton样式代码:
1 <Style x:Key="ColorButton" TargetType="Button"> 2 <Setter Property="Width" Value="200"></Setter> 3 <Setter Property="FontSize" Value="25"></Setter> 4 <Setter Property="Height" Value="60"></Setter> 5 <Setter Property="Foreground" Value="White"></Setter> 6 <Setter Property="Background" Value="{StaticResource MainColor}"></Setter> 7 <Setter Property="Template" > 8 <Setter.Value> 9 <ControlTemplate TargetType="Button"> 10 <Border Background="{TemplateBinding Background}" BorderBrush="{StaticResource MainColor}" 11 BorderThickness="1" x:Name="back"> 12 <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter> 13 </Border> 14 <ControlTemplate.Triggers> 15 <Trigger Property="IsMouseOver" Value="true"> 16 <Setter Property="Opacity" TargetName="back" Value="0.8"></Setter> 17 </Trigger> 18 <Trigger Property="IsPressed" Value="True"> 19 <Setter Property="Width" TargetName="back" Value="99"></Setter> 20 <Setter Property="Height" TargetName="back" Value="34"></Setter> 21 </Trigger> 22 </ControlTemplate.Triggers> 23 </ControlTemplate> 24 </Setter.Value> 25 </Setter> 26 </Style>
调用方式(略显啰嗦了。。):
1 private void CreateAlbumBtn_Click(object sender, RoutedEventArgs e) 2 { 3 CreateAlbum.ShowDialog(this); 4 }
最后,效果如下:
还原度,百分之百有没有..haha
登录设置模块
这一块呢,就比较简单了,主要就一个面板上放三个按钮;当然,都是自定义按钮;然后再设置个border就搞定;代码如下:
1 <Border Background="White" BorderThickness="0,0.3,0,0" BorderBrush="{StaticResource LineColor}" 2 VerticalAlignment="Bottom" Width="160" Height="60" HorizontalAlignment="Left" 3 Grid.ColumnSpan="2" Margin="0,0,0,0.4"> 4 <StackPanel Orientation="Horizontal"> 5 <Button Style="{StaticResource UserLoginButton}" Width="90">Michael</Button> 6 <local:FButton FIcon="" Margin="3" Style="{StaticResource FButton_Transparency}" HorizontalAlignment="Right" 7 ></local:FButton> 8 <local:FButton FIcon="" Margin="3" Style="{StaticResource FButton_Transparency}" HorizontalAlignment="Right" 9 ></local:FButton> 10 </StackPanel> 11 </Border>
自定义按钮:
1 <Style x:Key="UserLoginButton" TargetType="Button"> 2 <Setter Property="Template" > 3 <Setter.Value> 4 <ControlTemplate TargetType="Button"> 5 <StackPanel x:Name="back" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0" Orientation="Horizontal"> 6 <Ellipse x:Name="img" Width="30" Height="30"> 7 <Ellipse.Fill> 8 <ImageBrush ImageSource="/CloudMusic;component/Images/user.jpg"/> 9 </Ellipse.Fill> 10 </Ellipse> 11 <ContentPresenter VerticalAlignment="Center" Margin="5,0"/> 12 </StackPanel> 13 <ControlTemplate.Triggers> 14 <Trigger Property="IsMouseOver" Value="true"> 15 </Trigger> 16 <Trigger Property="IsPressed" Value="True"> 17 <Setter Property="Width" TargetName="img" Value="29"/> 18 <Setter Property="Height" TargetName="img" Value="29"/> 19 </Trigger> 20 </ControlTemplate.Triggers> 21 </ControlTemplate> 22 </Setter.Value> 23 </Setter> 24 </Style> 25 26 <!--背景透明的FButton样式--> 27 <Style x:Key="FButton_Transparency" TargetType="{x:Type local:FButton}"> 28 <Setter Property="Background" Value="Transparent" /> 29 <Setter Property="MouseOverBackground" Value="Transparent" /> 30 <Setter Property="PressedBackground" Value="Transparent" /> 31 <Setter Property="Foreground" Value="#777" /> 32 <Setter Property="MouseOverForeground" Value="{StaticResource MainColor}" /> 33 <Setter Property="PressedForeground" Value="{StaticResource MainPressedColor}" /> 34 <Setter Property="HorizontalContentAlignment" Value="Center" /> 35 <Setter Property="Height" Value="Auto" /> 36 <Setter Property="Width" Value="Auto" /> 37 <Setter Property="CornerRadius" Value="0" /> 38 <Setter Property="FontSize" Value="13" /> 39 <Setter Property="FIconSize" Value="20" /> 40 <Setter Property="Template" Value="{StaticResource FButton_Template}"/> 41 <Setter Property="Padding" Value="3,1,3,1" /> 42 <Setter Property="Content" Value="{x:Null}" /> 43 <Setter Property="FIconMargin" Value="0,0,2,0" /> 44 <Setter Property="AllowsAnimation" Value="False" /> 45 <Setter Property="Cursor" Value="Hand" /> 46 </Style> 47 <Style x:Key="FIcon" TargetType="TextBlock"> 48 <Setter Property="FontFamily" Value="/CloudMusic;component/Resources/#SF2015"></Setter> 49 <Setter Property="Foreground" Value="White"/> 50 <Setter Property="TextAlignment" Value="Center"/> 51 <Setter Property="HorizontalAlignment" Value="Center"/> 52 <Setter Property="VerticalAlignment" Value="Center"/> 53 <Setter Property="FontSize" Value="20"/> 54 </Style> 55 <!--FButton模板--> 56 <ControlTemplate x:Key="FButton_Template" TargetType="{x:Type local:FButton}"> 57 <Border x:Name="border" Background="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path= Background}" 58 Height="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Height}" 59 CornerRadius="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CornerRadius}" 60 BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 61 Width="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Width}"> 62 <!--Icon/Text--> 63 <StackPanel Orientation="Horizontal" VerticalAlignment="Center" 64 Margin="{TemplateBinding Padding}" 65 HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"> 66 <TextBlock x:Name="icon" Margin="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=FIconMargin}" 67 RenderTransformOrigin="0.5,0.5" Style="{StaticResource FIcon}" 68 Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path= FIcon}" 69 FontSize="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path= FIconSize}" 70 Foreground="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path= Foreground}"> 71 <TextBlock.RenderTransform> 72 <RotateTransform x:Name="transIcon" Angle="0"/> 73 </TextBlock.RenderTransform> 74 </TextBlock> 75 76 <TextBlock VerticalAlignment="Center" x:Name="txt" 77 TextDecorations="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ContentDecorations}" 78 Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Content}" 79 FontSize="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=FontSize}" 80 Foreground="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Foreground}"/> 81 </StackPanel> 82 </Border> 83 <!--触发器--> 84 <ControlTemplate.Triggers> 85 <!--设置鼠标进入时的背景、前景样式--> 86 <Trigger Property="IsMouseOver" Value="True"> 87 <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, 88 Path=MouseOverBackground}" TargetName="border" /> 89 <Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, 90 Path=MouseOverForeground}" TargetName="icon"/> 91 <Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, 92 Path=MouseOverForeground}" TargetName="txt"/> 93 </Trigger> 94 <!--Ficon的动画触发器--> 95 <MultiTrigger> 96 <MultiTrigger.Conditions> 97 <Condition Property="IsMouseOver" Value="true"></Condition> 98 <Condition Property="AllowsAnimation" Value="true"></Condition> 99 </MultiTrigger.Conditions> 100 <MultiTrigger.EnterActions> 101 <BeginStoryboard> 102 <Storyboard> 103 <DoubleAnimation Storyboard.TargetName="transIcon" Storyboard.TargetProperty="Angle" To="180" Duration="0:0:0.2" /> 104 </Storyboard> 105 </BeginStoryboard> 106 </MultiTrigger.EnterActions> 107 <MultiTrigger.ExitActions> 108 <BeginStoryboard> 109 <Storyboard> 110 <DoubleAnimation Storyboard.TargetName="transIcon" Storyboard.TargetProperty="Angle" To="0" Duration="0:0:0.2" /> 111 </Storyboard> 112 </BeginStoryboard> 113 </MultiTrigger.ExitActions> 114 </MultiTrigger> 115 <!--鼠标按下时的前景、背景样式--> 116 <Trigger Property="IsPressed" Value="True"> 117 <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, 118 Path=PressedBackground}" TargetName="border" /> 119 <Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, 120 Path=PressedForeground}" TargetName="icon"/> 121 <Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, 122 Path=PressedForeground}" TargetName="txt"/> 123 </Trigger> 124 <Trigger Property="IsEnabled" Value="false"> 125 <Setter Property="Opacity" Value="0.5" TargetName="border"/> 126 </Trigger> 127 </ControlTemplate.Triggers> 128 </ControlTemplate>
FButton cs代码:
1 public partial class FButton : Button 2 { 3 public static readonly DependencyProperty PressedBackgroundProperty = 4 DependencyProperty.Register("PressedBackground", typeof(Brush), typeof(FButton), new PropertyMetadata(Brushes.DarkBlue)); 5 /// <summary> 6 /// 鼠标按下背景样式 7 /// </summary> 8 public Brush PressedBackground 9 { 10 get { return (Brush)GetValue(PressedBackgroundProperty); } 11 set { SetValue(PressedBackgroundProperty, value); } 12 } 13 14 public static readonly DependencyProperty PressedSizeProperty = 15 DependencyProperty.Register("PressedSize", typeof(int), typeof(FButton), new PropertyMetadata(20)); 16 /// <summary> 17 /// 鼠标按下按钮大小 18 /// </summary> 19 public int PressedSize 20 { 21 get 22 { 23 if (this.FontSize - 1 != 20) return (int)this.FontSize - 1; 24 return (int)GetValue(PressedSizeProperty); 25 } 26 set { SetValue(PressedSizeProperty, value); } 27 } 28 29 30 public static readonly DependencyProperty PressedForegroundProperty = 31 DependencyProperty.Register("PressedForeground", typeof(Brush), typeof(FButton), new PropertyMetadata(Brushes.White)); 32 /// <summary> 33 /// 鼠标按下前景样式(图标、文字) 34 /// </summary> 35 public Brush PressedForeground 36 { 37 get { return (Brush)GetValue(PressedForegroundProperty); } 38 set { SetValue(PressedForegroundProperty, value); } 39 } 40 41 public static readonly DependencyProperty MouseOverBackgroundProperty = 42 DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(FButton), new PropertyMetadata(Brushes.RoyalBlue)); 43 /// <summary> 44 /// 鼠标进入背景样式 45 /// </summary> 46 public Brush MouseOverBackground 47 { 48 get { return (Brush)GetValue(MouseOverBackgroundProperty); } 49 set { SetValue(MouseOverBackgroundProperty, value); } 50 } 51 52 public static readonly DependencyProperty MouseOverForegroundProperty = 53 DependencyProperty.Register("MouseOverForeground", typeof(Brush), typeof(FButton), new PropertyMetadata(Brushes.White)); 54 /// <summary> 55 /// 鼠标进入前景样式 56 /// </summary> 57 public Brush MouseOverForeground 58 { 59 get { return (Brush)GetValue(MouseOverForegroundProperty); } 60 set { SetValue(MouseOverForegroundProperty, value); } 61 } 62 63 public static readonly DependencyProperty FIconProperty = 64 DependencyProperty.Register("FIcon", typeof(string), typeof(FButton), new PropertyMetadata("\ue604")); 65 /// <summary> 66 /// 按钮字体图标编码 67 /// </summary> 68 public string FIcon 69 { 70 get { return (string)GetValue(FIconProperty); } 71 set { SetValue(FIconProperty, value); } 72 } 73 74 public static readonly DependencyProperty FIconSizeProperty = 75 DependencyProperty.Register("FIconSize", typeof(int), typeof(FButton), new PropertyMetadata(20)); 76 /// <summary> 77 /// 按钮字体图标大小 78 /// </summary> 79 public int FIconSize 80 { 81 get { return (int)GetValue(FIconSizeProperty); } 82 set { SetValue(FIconSizeProperty, value); } 83 } 84 85 public static readonly DependencyProperty FIconMarginProperty = DependencyProperty.Register( 86 "FIconMargin", typeof(Thickness), typeof(FButton), new PropertyMetadata(new Thickness(0, 1, 3, 1))); 87 /// <summary> 88 /// 字体图标间距 89 /// </summary> 90 public Thickness FIconMargin 91 { 92 get { return (Thickness)GetValue(FIconMarginProperty); } 93 set { SetValue(FIconMarginProperty, value); } 94 } 95 96 public static readonly DependencyProperty AllowsAnimationProperty = DependencyProperty.Register( 97 "AllowsAnimation", typeof(bool), typeof(FButton), new PropertyMetadata(true)); 98 /// <summary> 99 /// 是否启用Ficon动画 100 /// </summary> 101 public bool AllowsAnimation 102 { 103 get { return (bool)GetValue(AllowsAnimationProperty); } 104 set { SetValue(AllowsAnimationProperty, value); } 105 } 106 107 public static readonly DependencyProperty CornerRadiusProperty = 108 DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(FButton), new PropertyMetadata(new CornerRadius(2))); 109 /// <summary> 110 /// 按钮圆角大小,左上,右上,右下,左下 111 /// </summary> 112 public CornerRadius CornerRadius 113 { 114 get { return (CornerRadius)GetValue(CornerRadiusProperty); } 115 set { SetValue(CornerRadiusProperty, value); } 116 } 117 118 public static readonly DependencyProperty ContentDecorationsProperty = DependencyProperty.Register( 119 "ContentDecorations", typeof(TextDecorationCollection), typeof(FButton), new PropertyMetadata(null)); 120 public TextDecorationCollection ContentDecorations 121 { 122 get { return (TextDecorationCollection)GetValue(ContentDecorationsProperty); } 123 set { SetValue(ContentDecorationsProperty, value); } 124 } 125 126 static FButton() 127 { 128 DefaultStyleKeyProperty.OverrideMetadata(typeof(FButton), new FrameworkPropertyMetadata(typeof(FButton))); 129 } 130 }
最后,效果如下:
咳咳,这个就不好意思再说 “还原度百分之百” 了,主要是没有专门去找后边两个按钮的图标,直接拿到手上现有的就用了;以上就是此篇文章的全部内容,请批评指正;
三.参考博客
弹出窗口蒙版:https://www.cnblogs.com/tsliwei/p/6212162.html
自定义按钮FButton: https://www.cnblogs.com/anding/p/4968050.html