2021-09-02 WPF上位机通用框架平台实战-登录窗口
Posted 微软MVP Eleven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-09-02 WPF上位机通用框架平台实战-登录窗口相关的知识,希望对你有一定的参考价值。
一:登录窗口布局和功能实现
<Window x:Class="Zhaoxi.HostComputer.Views.LoginWindow"
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:Zhaoxi.HostComputer.Views"
xmlns:vm="clr-namespace:Zhaoxi.HostComputer.ViewModels"
xmlns:base="clr-namespace:Zhaoxi.HostComputer.Base"
mc:Ignorable="d"
Background="Transparent" FontFamily="Microsoft YaHei" FontWeight="ExtraLight" ResizeMode="NoResize"
WindowStyle="None" AllowsTransparency="True" WindowStartupLocation="CenterScreen"
SizeToContent="WidthAndHeight"
Title="LoginWindow">
<Window.Resources>
<ControlTemplate TargetType="Button" x:Key="CloseButtonTemplate">
<Grid Background="Transparent" Name="back">
<TextBlock Text=""
FontFamily="{DynamicResource iconfont}" VerticalAlignment="Center" HorizontalAlignment="Center"
FontSize="14"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#DDD" TargetName="back"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style TargetType="TextBox" x:Key="UsernameTextBoxStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True"
CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border BorderBrush="#DDD" BorderThickness="0,0,1,0" Margin="0,8,5,8"/>
<TextBlock Text="请输入用户名" Grid.Column="1" VerticalAlignment="Center" Foreground="#BBB"
Name="markText" Visibility="Collapsed" FontSize="12" Margin="2,0"/>
<TextBlock Text=""
FontFamily="{DynamicResource iconfont}" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center"
Foreground="#DDD"/>
<ScrollViewer x:Name="PART_ContentHost" Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
Grid.Column="1"
VerticalAlignment="Center" MinHeight="20"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF569DE5"/>
</Trigger>
<DataTrigger Binding="{Binding Path=Text,RelativeSource={RelativeSource Mode=Self}}" Value="">
<Setter Property="Visibility" TargetName="markText" Value="Visible"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PasswordBoxStyle" TargetType="{x:Type PasswordBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True"
CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border BorderBrush="#DDD" BorderThickness="0,0,1,0" Margin="0,8,5,8"/>
<TextBlock Text="请输入密码" Grid.Column="1" VerticalAlignment="Center" Foreground="#BBB"
Name="markText" Visibility="Collapsed" FontSize="12" Margin="2,0"/>
<TextBlock Text="" FontFamily="{StaticResource iconfont}" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center"
Foreground="#DDD"/>
<ScrollViewer x:Name="PART_ContentHost" Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
Grid.Column="1"
VerticalAlignment="Center" MinHeight="20"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF569DE5"/>
</Trigger>
<DataTrigger Binding="{Binding Path=UserModel.Password}" Value="">
<Setter Property="Visibility" TargetName="markText" Value="Visible"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.5" To="0"
Storyboard.TargetName="tt"
Storyboard.TargetProperty="X"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid Width="740" Margin="5" Background="Transparent" MouseLeftButtonDown="Grid_MouseLeftButtonDown">
<Border Background="#F7F9FA" Margin="0,6" HorizontalAlignment="Right" Width="330" BorderBrush="#DDD" BorderThickness="0"
CornerRadius="0,5,5,0">
<Border.Effect>
<DropShadowEffect Color="Black" ShadowDepth="0" Direction="0" BlurRadius="10" Opacity="0.2"/>
</Border.Effect>
<Border.RenderTransform>
<TranslateTransform X="-350" x:Name="tt"/>
</Border.RenderTransform>
<Grid HorizontalAlignment="Right" Width="230" Margin="30,30,30,10">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="60"/>
<RowDefinition Height="auto" MinHeight="40"/>
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Center" Margin="0,0,0,30">
<TextBlock Text="智控平台" Foreground="#333" FontSize="22"/>
<TextBlock Text="专注于提升工业智能管理协作平台" FontSize="12" Foreground="#888" Margin="0,10,0,0"/>
</StackPanel>
<TextBox Grid.Row="1" Height="35" Margin="0,8" Style="{StaticResource UsernameTextBoxStyle}"
VerticalContentAlignment="Center" FontSize="14"
Text="{Binding UserModel.UserName,UpdateSourceTrigger=PropertyChanged}"/>
<PasswordBox Grid.Row="2" Height="35" Margin="0,8" Style="{StaticResource PasswordBoxStyle}"
base:PasswordBoxHelper.Attach="true"
base:PasswordBoxHelper.Password="{Binding UserModel.Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
FontSize="14"/>
<CheckBox Grid.Row="3" Content="记住登录信息" VerticalAlignment="Center" FontSize="10" VerticalContentAlignment="Center"/>
<TextBlock Grid.Row="3" HorizontalAlignment="Right" VerticalAlignment="Center">
<Hyperlink>忘记密码</Hyperlink>
</TextBlock>
<Button Content="登 录" Background="#FF104991" Foreground="White" Grid.Row="4" Height="30" Margin="0,8" BorderThickness="0" VerticalAlignment="Top"
Command="{Binding LoginCommand}" CommandParameter="{Binding Path=.,RelativeSource={RelativeSource AncestorType=Window}}"/>
<Button VerticalAlignment="Top" HorizontalAlignment="Right" Content="X" Margin="0,-30,-25,0"
Template="{StaticResource CloseButtonTemplate}" Width="40" Height="30"
Command="{Binding CloseCommand}" CommandParameter="{Binding Path=.,RelativeSource={RelativeSource AncestorType=Window}}"/>
<TextBlock Text="{Binding ErrorMsg}" Foreground="Red" TextWrapping="Wrap" Grid.Row="10"
TextAlignment="Center"/>
</Grid>
</Border>
<Polygon Points="0 0,420,0,450 200 420 400 0 400" StrokeThickness="0" Stroke="White" HorizontalAlignment="Left">
<Polygon.Fill>
<ImageBrush ImageSource="pack://application:,,,/Zhaoxi.HostComputer;component/Assets/Images/login_image.jpg" Stretch="UniformToFill" Viewbox="0,0,1.4,1">
</ImageBrush>
</Polygon.Fill>
<Polygon.Effect>
<DropShadowEffect Color="Black" ShadowDepth="0" Direction="0" BlurRadius="10" Opacity="0.3"/>
</Polygon.Effect>
</Polygon>
<Polygon Points="0 0,420,0,450 200 420 400 0 400" Opacity="0.2" StrokeThickness="0" Stroke="White" HorizontalAlignment="Left">
<Polygon.Fill>
<RadialGradientBrush>
<GradientStop Color="#22FFFFFF" Offset="0"/>
<GradientStop Color="#FF1B283C" Offset="1"/>
<GradientStop Color="#C6555F6E" Offset="0.617"/>
</RadialGradientBrush>
</Polygon.Fill>
</Polygon>
</Grid>
</Window>
/// <summary>
/// LoginWindow.xaml 的交互逻辑
/// </summary>
public partial class LoginWindow : Window
{
public LoginWindow()
{
InitializeComponent();
this.DataContext = new LoginViewModel();
}
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
}
public class UserModel : NotifyBase
{
private string _userName;
public string UserName
{
get { return _userName; }
set { _userName = value; this.NotifyChanged(); }
}
private string _password = "";
public string Password
{
get { return _password; }
set { _password = value; this.NotifyChanged(); }
}
public string RealName { get; set; }
public string Avatar { get; set; }
}
public class LoginViewModel : NotifyBase
{
LoginService loginService = new LoginService();
public UserModel UserModel { get; set; } = new UserModel();
private string _errorMsg;
public string ErrorMsg
{
get { return _errorMsg; }
set { _errorMsg = value; this.NotifyChanged(); }
}
private CommandBase _closeCommand;
public CommandBase CloseCommand
{
get
{
if (_closeCommand == null)
{
_closeCommand = new CommandBase();
_closeCommand.DoExecute = new Action<object>(obj =>
{
(obj as System.Windows.Window).DialogResult = false;
});
}
return _closeCommand;
}
}
private CommandBase _loginCommand;
public CommandBase LoginCommand
{
get
{
if (_loginCommand == null)
{
_loginCommand = new CommandBase();
_loginCommand.DoExecute = new Action<object>(obj =>
{
this.ErrorMsg = "";
try
{
if (loginService.CheckLogin(UserModel.UserName, UserModel.Password))
(obj as System.Windows.Window).DialogResult = true;
}
catch (Exception ex)
{
this.ErrorMsg = ex.Message;
}
});
}
return _loginCommand;
}
}
}
事件触发功能封装
public class CommandBase : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
DoExecute?.Invoke(parameter);
}
public Action<object> DoExecute { get; set; }
}
双向绑定功能封装
public class Notif以上是关于2021-09-02 WPF上位机通用框架平台实战-登录窗口的主要内容,如果未能解决你的问题,请参考以下文章
2021-09-04 WPF上位机通用框架平台实战-设备编辑
2021-09-04 WPF上位机通用框架平台实战-全局监控对象
2021-09-03 WPF上位机通用框架平台实战-Dashboard