HOME> 版本前瞻> WPF开发01-WPF界面设计

WPF开发01-WPF界面设计

@

目录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">

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">

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">

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 = new 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">

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 charList = new();

[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 GetResponseAsync(string url, HttpMethod method = null)

{

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 GetStringAsync(string url)

{

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 GetImageAsync(string url)

{

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: