@
目录1.设计一个优美的注册界面1.实现效果2.代码展示2.简易登录按钮设计1.实现效果2.代码展示3.设计一个优美的注册登录界面(连接数据库)1.实现效果2.代码展示4.设计一个简单的在线教育系统界面1.实现效果2.代码展示5. 设计一个Dashboard1.实现效果2.代码展示6.设计一个旋转风扇1.实现效果2.代码展示7.设计一个带有波浪效果的进度球1.实现效果2.代码展示8.设计一个圆形进度条1.简介2. 实现效果3.代码展示9.原神官网角色展示1.简介2. 实现效果3.代码展示10设计一个带按钮的多级树形控件1.简介2.实现效果3.代码展示11.
个人比较喜欢研究WPF界面设计, 此篇博客聚集了自己写过的一些WPF界面设计Demo。
1.设计一个优美的注册界面
1.实现效果
1.静态图:
2.动态图:
2.代码展示
1.文件结构:
2.MainWindow.xaml代码:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:fa="http://schemas.fontawesome.io/icons/" xmlns:uc="clr-namespace:RegisterPage.UserControls" mc:Ignorable="d" Title="MainWindow" Height="650" Width="850" Background="Transparent" WindowStyle="None" WindowStartupLocation="CenterScreen" AllowsTransparency="True">
MainWindow.xaml.cs代码:
using System.Windows;
using System.Windows.Input;
namespace RegisterPage
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Border_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)//如果按下了鼠标左键
{
this.DragMove();//允许拖动该窗口
}
}
}
}
3.App.xaml代码:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml">
App.xaml.cs代码:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace RegisterPage
{
///
/// App.xaml 的交互逻辑
///
public partial class App : Application
{
}
}
4.MyOption.xaml代码:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:fa="http://schemas.fontawesome.io/icons/" mc:Ignorable="d" Name="myOption">
MyOption.xaml.cs代码:
using System.Windows;
using System.Windows.Controls;
namespace RegisterPage.UserControls
{
///
/// MyOption.xaml 的交互逻辑
///
public partial class MyOption : UserControl
{
public MyOption()
{
InitializeComponent();
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
//DependencyProperty.Register方法:第一个参数是依赖属性的名字;第二个参数是依赖属性的类型;第三个参数是依赖属性所属的类名,也就是所有者类名;第四个参数是该属性的默认值
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MyOption));
public FontAwesome.WPF.FontAwesomeIcon Icon
{
get { return (FontAwesome.WPF.FontAwesomeIcon)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
//DependencyProperty.Register方法:第一个参数是依赖属性的名字;第二个参数是依赖属性的类型;第三个参数是依赖属性所属的类名,也就是所有者类名;第四个参数是该属性的默认值
public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(FontAwesome.WPF.FontAwesomeIcon), typeof(MyOption));
}
}
5.MyTextBox.xaml代码:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" Name="myTextBox"> Text="{Binding Path=Hint,ElementName=myTextBox}" Visibility="{Binding ElementName=textBox,Path=Text.IsEmpty,Converter={StaticResource boolToVis}}"/>
MyTextBox.xaml.cs代码:
using System.Windows;
using System.Windows.Controls;
namespace RegisterPage.UserControls
{
///
/// MyTextBox.xaml 的交互逻辑
///
public partial class MyTextBox : UserControl
{
public MyTextBox()
{
InitializeComponent();
}
public string Hint
{
get { return (string)GetValue(HintProperty); }
set { SetValue(HintProperty, value); }
}
//DependencyProperty.Register方法:第一个参数是依赖属性的名字;第二个参数是依赖属性的类型;第三个参数是依赖属性所属的类名,也就是所有者类名;第四个参数是该属性的默认值
public static readonly DependencyProperty HintProperty = DependencyProperty.Register("Hint", typeof(string), typeof(MyTextBox));
}
}
2.简易登录按钮设计
1.实现效果
2.代码展示
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:cms.Windows" mc:Ignorable="d" WindowStartupLocation="CenterScreen" Title="用户登录" Height="350" Width="600">
3.设计一个优美的注册登录界面(连接数据库)
1.实现效果
视频展示该界面:视频链接
2.代码展示
工程目录:
数据库部署:
LoginPage.xaml代码:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:local="clr-namespace:Login" mc:Ignorable="d" Title="登录" Height="760" Width="450" TextElement.Foreground="{DynamicResource MaterialDesignBody}" Background="{x:Null}" AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterScreen" Icon="/Image/loginPage.png">
LoginPage.xaml.cs代码:
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MaterialDesignThemes.Wpf;
namespace Login
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class LoginPage : Window
{
public LoginPage()
{
InitializeComponent();
}
public bool IsDarkTheme { get; set; }//定义一个属性
private readonly PaletteHelper paletteHelper = new PaletteHelper();
private void toggleTheme(object sender, RoutedEventArgs e)//切换主题的按钮点击事件
{
ITheme theme = paletteHelper.GetTheme();
if (IsDarkTheme = theme.GetBaseTheme() == BaseTheme.Dark)//如果当前主题颜色为暗黑色
{
IsDarkTheme = false;
theme.SetBaseTheme(Theme.Light);//设置主题颜色为明亮
}
else
{
IsDarkTheme = true;
theme.SetBaseTheme(Theme.Dark);//设置主题颜色为黑色
}
paletteHelper.SetTheme(theme);//成功设置界面主题颜色
}
private void exitApp(object sender, RoutedEventArgs e)//退出按钮点击事件
{
Application.Current.Shutdown();//退出该应用程序(即关掉该窗口)
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)//设置窗口可拖拽
{
base.OnMouseLeftButtonDown(e);
DragMove();
}
private void loginButtonClick(object sender, RoutedEventArgs e)//登录按钮点击事件
{
//与数据库进行连接;
//Server=小何表示服务器名称是小何;
//Database = accountList表示数据库名称为accountList;
//integrated security = true表示可以在不知道数据库用户名和密码的情况下时,依然可以连接数据库,
//如果integrated security = false, 或者不写,表示一定要输入正确的数据库登录名和密码。
SqlConnection sqlConnection = new SqlConnection(@"Server=小何;Database=accountList;Integrated Security=True");
sqlConnection.Open();
string add_data = "select * from [dbo].[User] where 用户名=@用户名 and 密码=@密码";
SqlCommand cmd = new SqlCommand(add_data, sqlConnection);
cmd.Parameters.AddWithValue("@用户名", txtUserName.Text);
cmd.Parameters.AddWithValue("@密码", txtPassword.Password);
cmd.ExecuteNonQuery();
int count=Convert.ToInt32(cmd.ExecuteScalar());
sqlConnection.Close();
txtUserName.Text = "";
txtPassword.Password = "";
if (count > 0)//数据库匹配成功
{
mainWindow mainWindow=new mainWindow();
this.Close();
mainWindow.Show();
}else//若返回-1,即匹配失败
{
MessageBox.Show("账号或密码输入错误!");
}
}
private void regisButtonClick(object sender, RoutedEventArgs e)//注册按钮点击事件
{
registPage reg1 = new registPage();
this.Close();
reg1.Show();
}
}
}
registPage.xaml代码:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" Title="Login" Height="760" Width="450" TextElement.Foreground="{DynamicResource MaterialDesignBody}" Background="{x:Null}" AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterScreen" Icon="/Image/registPage.png">
registPage.xaml.cs代码:
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Login
{
///
/// registPage.xaml 的交互逻辑
///
public partial class registPage : Window
{
public registPage()
{
InitializeComponent();
}
public bool IsDarkTheme { get; set; }//定义一个属性
private readonly PaletteHelper paletteHelper = new PaletteHelper();
private void toggleTheme(object sender, RoutedEventArgs e)//切换主题的按钮点击事件
{
ITheme theme = paletteHelper.GetTheme();
if (IsDarkTheme = theme.GetBaseTheme() == BaseTheme.Dark)//如果当前主题颜色为暗黑色
{
IsDarkTheme = false;
theme.SetBaseTheme(Theme.Light);//设置主题颜色为明亮
}
else
{
IsDarkTheme = true;
theme.SetBaseTheme(Theme.Dark);//设置主题颜色为黑色
}
paletteHelper.SetTheme(theme);//成功设置界面主题颜色
}
private void exitApp(object sender, RoutedEventArgs e)//退出按钮点击事件
{
Application.Current.Shutdown();//退出该应用程序(即关掉该窗口)
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)//设置窗口可拖拽
{
base.OnMouseLeftButtonDown(e);
DragMove();
}
private void backButtonClick(object sender, RoutedEventArgs e)
{
LoginPage mainWindow = new LoginPage();
this.Close();
mainWindow.Show();
}
private void registButtonClick(object sender, RoutedEventArgs e)//注册按钮点击事件
{
if (registPassword1.Password!=registPassword.Password)
{
MessageBox.Show("两次输入的密码不一致,请重新输入!");
registPassword.Password = "";
registPassword1.Password = "";
}
else
{
SqlConnection sqlConnection = new SqlConnection(@"Server=小何;Database=accountList;Integrated Security=True");
sqlConnection.Open();
string add_data = "insert into [dbo].[User] values(@用户名,@密码)";
SqlCommand cmd = new SqlCommand(add_data, sqlConnection);
cmd.Parameters.AddWithValue("@用户名", registUserName.Text);
cmd.Parameters.AddWithValue("@密码", registPassword.Password);
cmd.ExecuteNonQuery();
sqlConnection.Close();
registUserName.Text = "";
registPassword.Password = "";
registPassword1.Password = "";
MessageBox.Show("注册成功");
LoginPage mainWindow = new LoginPage();
this.Close();
mainWindow.Show();
}
}
}
}
App.xaml代码:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Login" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:viewModel="clr-namespace:Login.MVVM.ViewModel" xmlns:view="clr-namespace:Login.MVVM.View" StartupUri="LoginPage.xaml">
App.xaml.cs代码:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace Login
{
///
/// App.xaml 的交互逻辑
///
public partial class App : Application
{
}
}
而mainWindow则是一个新建的空窗口,没啥代码;
4.设计一个简单的在线教育系统界面
1.实现效果
2.代码展示
图片:
App.xaml
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:local="clr-namespace:WpfApp1" StartupUri="MainWindow.xaml">
App.xaml.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace WpfApp1
{
///
/// App.xaml 的交互逻辑
///
public partial class App : Application
{
}
}
MainWindow.xaml
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:customcontrols="clr-namespace:WpfApp1.customcontrols" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" x:Name="this" Title="MainWindow" Icon="/assets/icon.png" Height="735" Width="1024" Background="Transparent" FontSize="15" WindowStartupLocation="CenterScreen" WindowStyle="None" ResizeMode="NoResize" >
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp1
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)//设置窗口可拖拽
{
base.OnMouseLeftButtonDown(e);
DragMove();
}
}
}
MenuButton.xaml
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp1.customcontrols" mc:Ignorable="d" x:Name="this"> Stretch="Uniform" Width="{Binding IconWidth,ElementName=this,FallbackValue=10,TargetNullValue=10}" Style="{StaticResource MenuIconStyle}"/>
MenuButton.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp1.customcontrols
{
///
/// MenuButton.xaml 的交互逻辑
///
public partial class MenuButton : UserControl
{
public MenuButton()
{
InitializeComponent();
}
//下面是注册的一些依赖属性(快捷键:输入propdp,连续按两次tab键即可快捷注册依赖属性)
public PathGeometry Icon
{
get { return (PathGeometry)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
// Using a DependencyProperty as the backing store for Icon. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(PathGeometry), typeof(MenuButton));
public int IconWidth
{
get { return (int)GetValue(IconWidthProperty); }
set { SetValue(IconWidthProperty, value); }
}
// Using a DependencyProperty as the backing store for IconWidth. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IconWidthProperty =
DependencyProperty.Register("IconWidth", typeof(int), typeof(MenuButton));
public SolidColorBrush IndicatorBrush
{
get { return (SolidColorBrush)GetValue(IndicatorBrushProperty); }
set { SetValue(IndicatorBrushProperty, value); }
}
// Using a DependencyProperty as the backing store for IndicatorBrush. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IndicatorBrushProperty =
DependencyProperty.Register("IndicatorBrush", typeof(SolidColorBrush), typeof(MenuButton));
public int IndicatorCornerEadius
{
get { return (int)GetValue(IndicatorCornerEadiusProperty); }
set { SetValue(IndicatorCornerEadiusProperty, value); }
}
// Using a DependencyProperty as the backing store for IndicatorCornerEadius. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IndicatorCornerEadiusProperty =
DependencyProperty.Register("IndicatorCornerEadius", typeof(int), typeof(MenuButton));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
// Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(MenuButton));
public new Thickness Padding
{
get { return (Thickness)GetValue( PaddingProperty); }
set { SetValue( PaddingProperty, value); }
}
// Using a DependencyProperty as the backing store for Thickness Padding. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PaddingProperty =
DependencyProperty.Register(" Padding", typeof(Thickness), typeof(MenuButton));
public bool IsSelected
{
get { return (bool)GetValue(IsSelectedProperty); }
set { SetValue(IsSelectedProperty, value); }
}
// Using a DependencyProperty as the backing store for IsSelected. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsSelectedProperty =
DependencyProperty.Register("IsSelected", typeof(bool), typeof(MenuButton));
public string GroupName
{
get { return (string)GetValue(GroupNameProperty); }
set { SetValue(GroupNameProperty, value); }
}
// Using a DependencyProperty as the backing store for GroupName. This enables animation, styling, binding, etc...
public static readonly DependencyProperty GroupNameProperty =
DependencyProperty.Register("GroupName", typeof(string), typeof(MenuButton));
}
}
StreamingStatusButton.xaml
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp1.customcontrols" mc:Ignorable="d" x:Name="this">
StreamingStatusButton.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp1.customcontrols
{
///
/// StreamingStatusButton.xaml 的交互逻辑
///
public partial class StreamingStatusButton : UserControl
{
public StreamingStatusButton()
{
InitializeComponent();
}
//注册依赖属性
public Uri ImageSource
{
get { return (Uri)GetValue(ImageSourceProperty); }
set { SetValue(ImageSourceProperty, value); }
}
// Using a DependencyProperty as the backing store for ImageSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ImageSourceProperty =
DependencyProperty.Register("ImageSource", typeof(Uri), typeof(StreamingStatusButton));
}
}
5. 设计一个Dashboard
1.实现效果
2.代码展示
需要安装一个包,来加载图标资源
工程结构:
App.xaml:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp1" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" StartupUri="MainWindow.xaml" xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2"> [an error occurred while processing the directive] [an error occurred while processing the directive]
App.xaml.cs:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace WpfApp1
{
///
/// Interaction logic for App.xaml
///
public partial class App : Application
{
}
}
MainWindow.xaml:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" Title="MainWindow" Height="720" Width="1080" AllowsTransparency="True" Background="Transparent" WindowStartupLocation="CenterScreen" WindowStyle="None">
MainWindow.xaml.cs:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp1
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var converter=new BrushConverter();
ObservableCollection
members.Add(new Member { Number = "1", Character = "Q", BgColor = (Brush)converter.ConvertFromString("#ff6551"), Name = "wetr", Position = "ert", Email = "123456@gmail.com", Phone = "1234567890" });
members.Add(new Member { Number = "2", Character = "W", BgColor = (Brush)converter.ConvertFromString("#ff5c91"), Name = "ret", Position = "uytry", Email = "123456@gmail.com", Phone = "1234567890" });
members.Add(new Member { Number = "3", Character = "E", BgColor = (Brush)converter.ConvertFromString("#d56fe5"), Name = "tyr", Position = "ytu", Email = "123456@gmail.com", Phone = "1234567890" });
members.Add(new Member { Number = "4", Character = "R", BgColor = (Brush)converter.ConvertFromString("#ad82f2"), Name = "uyi", Position = "uyti", Email = "123456@gmail.com", Phone = "1234567890" });
members.Add(new Member { Number = "5", Character = "T", BgColor = (Brush)converter.ConvertFromString("#8590e9"), Name = "iio", Position = "ui", Email = "123456@gmail.com", Phone = "1234567890" });
members.Add(new Member { Number = "6", Character = "Y", BgColor = (Brush)converter.ConvertFromString("#42a5f5"), Name = "uyoi", Position = "jhk", Email = "123456@gmail.com", Phone = "1234567890" });
membersDataGrid.ItemsSource = members;
}
private void Border_MouseDown(object sender, MouseButtonEventArgs e)
{
if(e.ChangedButton==MouseButton.Left)
{
this.DragMove();
}
}
private bool IsMAximized=false;
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if(e.ClickCount==2)//鼠标左键双击
{
if (IsMAximized)
{
this.WindowState = WindowState.Normal;
this.Width = 1080;
this.Height = 720;
IsMAximized = false;
}else
{
this.WindowState=WindowState.Maximized;
IsMAximized=true;
}
}
}
}
public class Member
{
public string Character { get; set; }
public string Number { get; set; }
public string Name { get; set; }
public string Position { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public Brush BgColor { get; set; }
}
}
6.设计一个旋转风扇
1.实现效果
2.代码展示
MainWindow.xaml代码:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp2" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800">
MainWindow.xaml.cs代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp2
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
Storyboard storyboard = null;
public MainWindow()
{
InitializeComponent();
storyboard = Resources["FanAnimation"] as Storyboard;//从View页面中定义的资源字典中拿到名为FanAnimation的资源
}
private void btnOpen_Click(object sender, RoutedEventArgs e)
{
storyboard.Begin();
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
storyboard.Stop();
}
}
}
7.设计一个带有波浪效果的进度球
1.实现效果
2.代码展示
MainWindow.xaml代码:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp2" Topmost="True" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800">
MainWindow.xaml.cs代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp2
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void slider01_ValueChanged(object sender, RoutedPropertyChangedEventArgs
{
this.trans.Y = 160 - e.NewValue;
}
}
}
8.设计一个圆形进度条
1.简介
主要用StrokeDashArray来绘制图形。
思路:
用Rectangle来画2个圆环,一个浅色作为进度条的背景,一个深色作为进度条进度显示。
然后通过设置StrokeDashArray来调整进度的多少,并通过StrokeDashCap把进度条两端也弄成圆弧。但是值得注意的是,通过设置StrokeDashArray来调整进度的多少,设置的并不是1%的进度,而是圆弧长度,因此还需要其他方法来设置进度条进度。
通过TextBox中输入的值来手动设置进度值,并通过TextChanged事件来刷新进度条进度。
接下来主要就是计算百分比的问题:
StrokeDashArray的单位长度不是1,而是StrokeThickness,所以整个StrokeDashArray的长度是这个圆环的周长,但是要用StrokeThickness的值为单位。
2. 实现效果
3.代码展示
MainWindow.xaml代码:
x:Class="BlankApp1.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" Title="{Binding Title}" Width="525" Height="350" prism:ViewModelLocator.AutoWireViewModel="True">
MainWindow.xaml.cs代码:
using System;
using System.Windows;
using System.Windows.Media;
namespace BlankApp1.Views
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void txt_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
double pro = 0;
try
{
pro = Convert.ToDouble(txt.Text);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
CaluculateProgress(pro,progressBar.RadiusX,progressBar.StrokeThickness);
}
}
void CaluculateProgress(double pro,double radius,double thickness)
{
double r = radius - thickness / 2;///圆环半径,计算方法为:外弧半径-thickness的一半
double perimeter = 2 * Math.PI * r / thickness;//圆弧长度,计算方法为:圆弧的周长除以单位长度
double step = pro / 100*perimeter;//进度,计算方法为:圆弧的长度除以比例
progressBar.StrokeDashArray = new DoubleCollection() { step, 100 };
}
}
}
9.原神官网角色展示
1.简介
转自:《原神》官网角色展示界面的WPF实现。觉得原作者的代码中有很多学习地方,故摘抄下来学习。
简介:
代码中有一些自定义动画、自定义按钮、自定义进度条以及json对象操作。
2. 实现效果
3.代码展示
文件结构:
MainWindow.xaml代码:
ConnectionFailed.xaml代码:
MainWindowViewModel.cs代码:
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using GenshinCharacterBrowser.Helpers;
using GenshinCharacterBrowser.Models;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.ObjectModel;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
namespace GenshinCharacterBrowser.ViewModels;
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
ObservableCollection
[ObservableProperty]
Character selectedItem;
[ObservableProperty]
BitmapImage dawnImage;
[ObservableProperty]
BitmapImage duskImage;
[ObservableProperty]
bool connectionFailed;
string lastVisitedCity = null;
[RelayCommand]
async Task LoadCity(string id)
{
lastVisitedCity = id;
try
{
var result = await HttpHelper.GetStringAsync($"https://content-static.mihoyo.com/content/ysCn/getContentList?pageSize=20&pageNum=1&order=asc&channelId={id}");
var list = JObject.Parse(result)["data"]["list"];
CharList.Clear();
foreach (var item in list)
{
CharList.Add(new(item));
}
SelectedItem = CharList[0];
await ChangeBg(id);
}
catch (HttpRequestException)
{
ConnectionFailed = true;
return;
}
}
async Task ChangeBg(string id)
{
var dawnUrl = id switch
{
"150" => @"https://uploadstatic.mihoyo.com/contentweb/20200211/2020021114220951905.jpg",
"151" => @"https://uploadstatic.mihoyo.com/contentweb/20200515/2020051511073340128.jpg",
"324" => @"https://uploadstatic.mihoyo.com/contentweb/20210719/2021071917030766463.jpg",
"350" => @"https://webstatic.mihoyo.com/upload/contentweb/2022/08/15/04d542b08cdee91e5dabfa0e85b8995e_8653892990016707198.jpg",
_ => throw new ArgumentException(id)
};
var duskUrl = id switch
{
"150" => @"https://uploadstatic.mihoyo.com/contentweb/20200211/2020021114221470532.jpg",
"151" => @"https://uploadstatic.mihoyo.com/contentweb/20200515/2020051511072867344.jpg",
"324" => @"https://uploadstatic.mihoyo.com/contentweb/20210719/2021071917033032133.jpg",
"350" => @"https://webstatic.mihoyo.com/upload/contentweb/2022/08/15/ab72edd8acc105904aa50da90e4e788e_2299455865599609620.jpg",
_ => throw new ArgumentException(id)
};
var dawn = HttpHelper.GetImageAsync(dawnUrl);
var dusk = HttpHelper.GetImageAsync(duskUrl);
await Task.WhenAll(dawn, dusk);
DawnImage = dawn.Result;
DuskImage = dusk.Result;
}
[RelayCommand]
async Task RetryClick()
{
ConnectionFailed = false;
await LoadCity(lastVisitedCity);
}
}
Character.cs代码:
using Newtonsoft.Json.Linq;
using System.Linq;
namespace GenshinCharacterBrowser.Models;
public class Character
{
public string Name { get; init; }
public string IconUrl { get; init; }
public string ProtraitUrl { get; init; }
public string NameUrl { get; set; }
public string ElementUrl { get; set; }
public string DialogueUrl { get; set; }
public Character() { }
public Character(JToken obj)
{
Name = obj["title"].ToString();
IconUrl = obj["ext"].First(v => v["arrtName"].ToString() == "角色-ICON")["value"][0]["url"].ToString();
ProtraitUrl = obj["ext"].First(v => v["arrtName"].ToString() == "角色-PC端主图")["value"][0]["url"].ToString();
NameUrl = obj["ext"].First(v => v["arrtName"].ToString() == "角色-名字")["value"][0]["url"].ToString();
ElementUrl = obj["ext"].First(v => v["arrtName"].ToString() == "角色-属性")["value"][0]["url"].ToString();
DialogueUrl = obj["ext"].First(v => v["arrtName"].ToString() == "角色-台词")["value"][0]["url"].ToString();
}
}
HttpHelper.cs代码:
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
namespace GenshinCharacterBrowser.Helpers;
public static class HttpHelper
{
private static HttpClient httpClient = new();
///
/// Get an http response from sending request to a specific url
///
///
/// Http method being used (default:
///
public static async Task
{
using var request = new HttpRequestMessage
{
RequestUri = new Uri(url),
Method = method ?? HttpMethod.Get
};
var response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return response;
}
///
/// Get string content from a specific url
///
///
///
public static async Task
{
using var response = await GetResponseAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
///
/// Get a bitmap image from a specific url
///
public static async Task
{
using var response = await GetResponseAsync(url);
var data = await response.Content.ReadAsByteArrayAsync();
using var stream = new MemoryStream(data);
var image = new BitmapImage();
image.BeginInit();
image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = null;
image.StreamSource = stream;
image.EndInit();
image.Freeze();
return image;
}
}
BoolToVisibilityConverter.cs代码:
using System;
using System.Globalization;
using System.Windows;
namespace GenshinCharacterBrowser.Converters;
public class BoolToVisibilityConverter : BaseValueConverter
{
public bool IsReverse { get; set; }
public bool UseHidden { get; set; }
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var res = System.Convert.ToBoolean(value);
if (IsReverse) res = !res;
if (res) return Visibility.Visible;
else return UseHidden ? Visibility.Hidden : Visibility.Collapsed;
}
public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var vis = (Visibility)value;
bool res = vis != Visibility.Visible;
if (IsReverse) res = !res;
return res;
}
}
BaseValueConverter.cs代码:
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
namespace GenshinCharacterBrowser.Converters;
public abstract class BaseValueConverter : MarkupExtension, IValueConverter
{
public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture);
public abstract object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
图片:
10设计一个带按钮的多级树形控件
1.简介
参考链接:WPF 中 TreeListView 的使用。
2.实现效果
3.代码展示
View:
ViewModel:
public class Staff : ViewModelBase
{
private string _Name;
private int _Age;
private string _Sex;
private string _Duty;
private bool _IsSelected;
private bool _IsExpanded;
private ObservableCollection
public ObservableCollection
{
get { return _StaffList; }
set
{
_StaffList = value;
OnPropertyChanged();
}
}
///
/// 姓名
///
public string Name
{
get { return _Name; }
set
{
_Name = value;
OnPropertyChanged();
}
}
///
/// 年龄
///
public int Age
{
get { return _Age; }
set
{
_Age = value;
OnPropertyChanged();
}
}
///
/// 性别
///
public string Sex
{
get { return _Sex; }
set
{
_Sex = value;
OnPropertyChanged();
}
}
///
/// 职务
///
public string Duty
{
get { return _Duty; }
set
{
_Duty = value;
OnPropertyChanged();
}
}
///
/// 是否选中
///
public bool IsSelected
{
get { return _IsSelected; }
set
{
_IsSelected = value;
OnPropertyChanged();
}
}
///
/// 是否展开
///
public bool IsExpanded
{
get { return _IsExpanded; }
set
{
_IsExpanded = value;
OnPropertyChanged();
}
}
public Staff()
{
IsSelected = false;
IsExpanded = false;
}
}
public class RecipeMainViewModel:ViewModelBase
{
private ObservableCollection
public ObservableCollection
{
get { return _StaffList; }
set
{
_StaffList = value;
OnPropertyChanged();
}
}
public RecipeMainViewModel()
{
Staff staff = new Staff()
{
Name = "配方",
Age = 30,
Sex = "男",
Duty = "经理",
IsExpanded = true
};
Staff staff2 = new Staff()
{
Name = "配方1",
Age = 21,
Sex = "男",
Duty = "员工",
IsExpanded = true
};
Staff staff3 = new Staff()
{
Name = "配方11",
Age = 21,
Sex = "男",
Duty = "员工"
};
Staff staff31 = new Staff()
{
Name = "配方111",
Age = 21,
Sex = "男",
Duty = "员工"
};
staff3.StaffList.Add(staff31);
staff2.StaffList.Add(staff3);
staff3 = new Staff()
{
Name = "配方22",
Age = 21,
Sex = "女",
Duty = "员工"
};
staff2.StaffList.Add(staff3);
staff.StaffList.Add(staff2);
staff2 = new Staff()
{
Name = "配方2",
Age = 22,
Sex = "女",
Duty = "员工"
};
staff.StaffList.Add(staff2);
staff2 = new Staff()
{
Name = "配方3",
Age = 23,
Sex = "女",
Duty = "员工"
};
staff.StaffList.Add(staff2);
StaffList.Add(staff);
staff = new Staff()
{
Name = "配方2",
Age = 31,
Sex = "男",
Duty = "副经理"
};
staff2 = new Staff()
{
Name = "李四1",
Age = 24,
Sex = "女",
Duty = "员工"
};
staff.StaffList.Add(staff2);
staff2 = new Staff()
{
Name = "李四2",
Age = 25,
Sex = "女",
Duty = "员工"
};
staff.StaffList.Add(staff2);
staff2 = new Staff()
{
Name = "李四3",
Age = 26,
Sex = "男",
Duty = "员工"
};
staff.StaffList.Add(staff2);
StaffList.Add(staff);
staff = new Staff()
{
Name = "王五",
Age = 32,
Sex = "女",
Duty = "组长"
};
staff2 = new Staff()
{
Name = "王五1",
Age = 27,
Sex = "女",
Duty = "员工"
};
staff.StaffList.Add(staff2);
staff2 = new Staff()
{
Name = "王五2",
Age = 28,
Sex = "女",
Duty = "员工"
};
staff.StaffList.Add(staff2);
StaffList.Add(staff);
}
}
Converter:
///
/// Convert Level to left margin
/// Pass a prarameter if you want a unit length other than 19.0.
///
public class LevelToIndentConverter : IValueConverter
{
public object Convert(object o, Type type, object parameter,
CultureInfo culture)
{
return new Thickness((int)o * c_IndentSize, 0, 0, 0);
}
public object ConvertBack(object o, Type type, object parameter,
CultureInfo culture)
{
throw new NotSupportedException();
}
private const double c_IndentSize = 19.0;
}
11.