目录
第一步:创建项目后下载如下两个NuGet程序包,然后删除删掉using Microsoft.Practices.ServiceLocation; 并且引入using CommonServiceLocator;
第二步:删除原来的XAML文件并创建如下的包结构然后创建一个在View文件夹中创建一个Main窗体 再将App.XAML中的StartupUri修改为View/Main.xaml
第三步:创建Model层中的文件UserInfo和Todo
UserInfo的类如下:
Todo的类如下:
第四步:创建Service层IUserInfoService接口和ITodoService接口
IUserInfoService接口如下:
ITodoService接口如下:
第五步:配置连接字符串 并将连接的内容封装到Tool文件夹中的ConstHelper
ConstHelper类如下:
第六步:在ServiceImpl文件夹实现Service层中的接口
UserInfoService类如下:
TodoService类如下:
第七步:在View文件夹中创建Login.XAML文件 并将App.XAML文件进行修改
1.将StartupUri删除
2.添加 ShutdownMode="OnExplicitShutdown"和Startup="Application_Startup"
3.在App.xaml.cs中写如下代码:
第8步:在Tool文件夹中创建LoginInfo在ViewModel文件夹中创建LoginViewModel
LoginInfo类如下:
LoginViewModel类如下:
第九步:将页面和类放入Ioc容器中并设计将View文件夹中
ViewModelLocator类如下:
Login.XAML中的内容如下:
第十步:将View文件中的Main.XAML写好 然后写好ViewModel中的MainViewModel 最后创建两个UC
1.Main.XAML如下:
2.MainViewModel如下:
3.创建两个Contorls
UCUserInfo如下:
UCTodo如下:
最后的效果如下:
登录界面:
点击登录后进入Main窗体:
点击任务管理后:
第一步:创建项目后下载如下两个NuGet程序包,然后删除删掉using Microsoft.Practices.ServiceLocation; 并且引入using CommonServiceLocator;
第二步:删除原来的XAML文件并创建如下的包结构然后创建一个在View文件夹中创建一个Main窗体 再将App.XAML中的StartupUri修改为View/Main.xaml
第三步:创建Model层中的文件UserInfo和Todo
UserInfo的类如下:
using GalaSoft.MvvmLight;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;namespace WPF练习12简单的项目.Model
{public class UserInfo : ObservableObject{[Key]public int UserId { get; set; }[Required(ErrorMessage = "账号必填")][Column(TypeName = "varchar(50)")]public string Account { get; set; }[Required(ErrorMessage = "密码必填")][Column(TypeName = "varchar(50)")]public string Pwd { get; set; }}
}
Todo的类如下:
using GalaSoft.MvvmLight;
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;namespace WPF练习12简单的项目.Model
{public class Todo:ObservableObject{[Key]public int TodoId { get; set; }[Required(ErrorMessage = "任务标题必填")][Column(TypeName = "varchar(50)")]public string Title { get; set; }[Column(TypeName = "varchar(150)")]public string Detail { get; set; }[Required(ErrorMessage = "是否完成必填")][Column(TypeName = "bit")]public bool IsCompleted { get; set; } = false;[Required(ErrorMessage = "创建人Id必填")][Column(TypeName = "int")]public int CreateUserId { get; set; }[Required(ErrorMessage = "创建日期必填")][Column(TypeName = "datetime")]public DateTime CreateTime { get; set; } = DateTime.Now;}
}
第四步:创建Service层IUserInfoService接口和ITodoService接口
IUserInfoService接口如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WPF练习12简单的项目.Model;namespace WPF练习12简单的项目.Service
{public interface IUserInfoService{bool Add(UserInfo model);bool Delete(int id);bool Update(UserInfo model);List<UserInfo> GetList(string strWhere);List<UserInfo> GetListByPage(string strWhere, string orderBy, int startIndex, int endIndex);UserInfo GetModel(int id);}
}
ITodoService接口如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WPF练习12简单的项目.Model;namespace WPF练习12简单的项目.Service
{public interface ITodoService{bool Add(Todo model);bool Delete(int id);bool Update(Todo model);List<Todo> GetList(string strWhere);List<Todo> GetListByPage(string strWhere, string orderBy, int startIndex, int endIndex);int GetCount(string strWhere);Todo GetModel(int id);}
}
第五步:配置连接字符串 并将连接的内容封装到Tool文件夹中的ConstHelper
ConstHelper类如下:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace WPF练习12简单的项目.Tool
{public static class ConstHelper{public static string ConnectionString { get; } = ConfigurationManager.ConnectionStrings["connString"].ConnectionString;}
}
第六步:在ServiceImpl文件夹实现Service层中的接口
UserInfoService类如下:
using Dapper;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WPF练习12简单的项目.Model;
using WPF练习12简单的项目.Service;
using WPF练习12简单的项目.Tool;namespace WPF练习12简单的项目.ServiceImpl
{public class UserInfoService:IUserInfoService{public bool Add(UserInfo model){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "INSERT INTO UserInfo(Account, Pwd) VALUES (@Account, @Pwd)";return conn.Execute(sql, model) > 0;}}public bool Delete(int id){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "DELETE FROM UserInfo WHERE UserId=@UserId";var paramter = new { UserId = id };return conn.Execute(sql, paramter) > 0;}}public List<UserInfo> GetList(string strWhere){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "SELECT UserId, Account, Pwd FROM UserInfo WHERE 1=1 ";if (!string.IsNullOrEmpty(strWhere)) sql += $" AND {strWhere}";return conn.Query<UserInfo>(sql).ToList();}}public List<UserInfo> GetListByPage(string strWhere, string orderBy, int startIndex, int endIndex){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();StringBuilder sql = new StringBuilder();sql.Append("SELECT * FROM ( ");sql.Append(" SELECT ROW_NUMBER() OVER (");if (!string.IsNullOrEmpty(orderBy.Trim()))sql.Append("ORDER BY T." + orderBy);elsesql.Append("ORDER BY T.UserId DESC");sql.Append(")AS Row, T.* FROM [User] T ");if (!string.IsNullOrEmpty(strWhere.Trim())){sql.Append(" WHERE " + strWhere);}sql.Append(" ) TT");sql.AppendFormat(" WHERE TT.Row BETWEEN {0} AND {1}", startIndex, endIndex);return conn.Query<UserInfo>(sql.ToString()).ToList();}}public UserInfo GetModel(int id){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "SELECT UserId, Account, Pwd FROM UserInfo WHERE UserId=@UserId";var parameter = new { UserId = id };return conn.QueryFirstOrDefault<UserInfo>(sql, parameter);}}public bool Update(UserInfo model){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "UPDATE UserInfo SET Account=@Account, Pwd=@Pwd WHERE UserId=@UserId";return conn.Execute(sql, model) > 0;}}}
}
TodoService类如下:
using Dapper;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WPF练习12简单的项目.Model;
using WPF练习12简单的项目.Service;
using WPF练习12简单的项目.Tool;namespace WPF练习12简单的项目.ServiceImpl
{public class TodoService : ITodoService{public bool Add(Todo model){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "INSERT INTO [Todo](Title, Detail, IsCompleted, CreateUserId, CreateTime) VALUES (@Title, @Detail, @IsCompleted, @CreateUserId, @CreateTime)";return conn.Execute(sql, model) > 0;}}public bool Delete(int id){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "DELETE FROM [Todo] WHERE TodoId=@TodoId";var paramter = new { TodoId = id };return conn.Execute(sql, paramter) > 0;}}public List<Todo> GetList(string strWhere){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "SELECT TodoId, Title, Detail, IsCompleted, CreateUserId, CreateUserName, CreateTime FROM [TodoView] WHERE 1=1 ";if (!string.IsNullOrEmpty(strWhere)) sql += $" AND {strWhere}";return conn.Query<Todo>(sql).ToList();}}public List<Todo> GetListByPage(string strWhere, string orderBy, int startIndex, int endIndex){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();StringBuilder sql = new StringBuilder();sql.Append("SELECT * FROM ( ");sql.Append(" SELECT ROW_NUMBER() OVER (");if (!string.IsNullOrEmpty(orderBy.Trim()))sql.Append("ORDER BY T." + orderBy);elsesql.Append("ORDER BY T.TodoId DESC");sql.Append(")AS Row, T.* FROM [TodoView] T ");if (!string.IsNullOrEmpty(strWhere.Trim())){sql.Append(" WHERE " + strWhere);}sql.Append(" ) TT");sql.AppendFormat(" WHERE TT.Row BETWEEN {0} AND {1}", startIndex, endIndex);return conn.Query<Todo>(sql.ToString()).ToList();}}public int GetCount(string strWhere){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "SELECT COUNT(TodoId) FROM [Todo] WHERE 1=1 ";if (!string.IsNullOrEmpty(strWhere)) sql += $" AND {strWhere}";return conn.ExecuteScalar<int>(sql);}}public Model.Todo GetModel(int id){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "SELECT TodoId, Title, Detail, IsCompleted, CreateUserId, CreateTime FROM [Todo] WHERE TodoId=@TodoId";var parameter = new { TodoId = id };return conn.QueryFirstOrDefault<Model.Todo>(sql, parameter);}}public bool Update(Model.Todo model){using (var conn = new SqlConnection(ConstHelper.ConnectionString)){conn.Open();var sql = "UPDATE [Todo] SET Title=@Title, Detail=@Detail, IsCompleted=@IsCompleted, CreateUserId=@CreateUserId, CreateTime=@CreateTime WHERE TodoId=@TodoId";return conn.Execute(sql, model) > 0;}}}
}
第七步:在View文件夹中创建Login.XAML文件 并将App.XAML文件进行修改
1.将StartupUri删除
2.添加 ShutdownMode="OnExplicitShutdown"和Startup="Application_Startup"
3.在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;
using WPF练习12简单的项目.View;namespace WPF练习12简单的项目
{/// <summary>/// App.xaml 的交互逻辑/// </summary>public partial class App : Application{private void Application_Startup(object sender, StartupEventArgs e){Login loginWindow = new Login();bool? result = loginWindow.ShowDialog();if (result == true){Main main = new Main();main.ShowDialog();}}}
}
第8步:在Tool文件夹中创建LoginInfo在ViewModel文件夹中创建LoginViewModel
LoginInfo类如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WPF练习12简单的项目.Model;namespace WPF练习12简单的项目.Tool
{public static class LoginInfo{public static UserInfo CurrentUser { get; set; }}
}
LoginViewModel类如下:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using WPF练习12简单的项目.Model;
using WPF练习12简单的项目.Service;
using WPF练习12简单的项目.Tool;
using WPF练习12简单的项目.View;namespace WPF练习12简单的项目.ViewModel
{public class LoginViewModel: ViewModelBase{private readonly IUserInfoService userService;public LoginViewModel(IUserInfoService userService){this.userService = userService;}private UserInfo user = new UserInfo();public UserInfo User{get { return user; }set { user = value; RaisePropertyChanged(); }}public RelayCommand<Login> LoginCommand{get{return new RelayCommand<Login>((Login win) =>{Button btnLogin = win.FindName("btnLogin") as Button;btnLogin.Focus();List<UserInfo> list = this.userService.GetList($" Account='{User.Account}' AND Pwd='{User.Pwd}'");if (list.Count == 0){MessageBox.Show("账号或密码有误!", "错误", MessageBoxButton.OK, MessageBoxImage.Error);return;}if (list.Count > 1){MessageBox.Show("账号重复,请联系管理员!", "错误", MessageBoxButton.OK, MessageBoxImage.Error);return;}LoginInfo.CurrentUser = list[0];win.DialogResult = true;});}}}
}
第九步:将页面和类放入Ioc容器中并设计将View文件夹中
ViewModelLocator类如下:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using CommonServiceLocator;
using WPF练习简单的项目12.ViewModel;
using WPF练习12简单的项目.Service;
using WPF练习12简单的项目.ServiceImpl;namespace WPF练习12简单的项目.ViewModel
{/// <summary>/// This class contains static references to all the view models in the/// application and provides an entry point for the bindings./// </summary>public class ViewModelLocator{/// <summary>/// Initializes a new instance of the ViewModelLocator class./// </summary>public ViewModelLocator(){ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);// 注册是窗体的视图模型SimpleIoc.Default.Register<LoginViewModel>();SimpleIoc.Default.Register<MainViewModel>();// 注册是用户控件的视图模型//SimpleIoc.Default.Register<UCUserViewModel>();//SimpleIoc.Default.Register<UCTodoViewModel>();//SimpleIoc.Default.Register<UCPagerViewModel>();// 注册其他服务SimpleIoc.Default.Register<IUserInfoService, UserInfoService>();SimpleIoc.Default.Register<ITodoService, TodoService>();}public MainViewModel Main{get{return ServiceLocator.Current.GetInstance<MainViewModel>();}}public LoginViewModel Login{get { return ServiceLocator.Current.GetInstance<LoginViewModel>(); }}public static void Cleanup(){// TODO Clear the ViewModels}}
}
Login.XAML中的内容如下:
<Window x:Class="WPF练习12简单的项目.View.Login"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:WPF练习12简单的项目.View"xmlns:viewmodel="clr-namespace:WPF练习12简单的项目.ViewModel"d:DataContext="{d:DesignInstance Type=viewmodel:LoginViewModel}"DataContext="{Binding Source={StaticResource Locator}, Path=Login}"FocusManager.FocusedElement="{Binding ElementName=txtAccount}"WindowStartupLocation="CenterScreen"mc:Ignorable="d"Title="Login"Height="250"Width="400"><Grid HorizontalAlignment="Center"VerticalAlignment="Center"><StackPanel><WrapPanel Margin="0,0,0,10"><Label Content="账号:" /><TextBox Name="txtAccount"Width="120"Height="30"Padding="5,0,0,0"VerticalContentAlignment="Center"Text="{Binding UserInfo.Account}" /></WrapPanel><WrapPanel Margin="0,0,0,10"><Label Content="密码:" /><TextBox Width="120"Height="30"Padding="5,0,0,0"VerticalContentAlignment="Center"Text="{Binding UserInfo.Pwd}" /></WrapPanel><WrapPanel Margin="0,0,0,10"HorizontalAlignment="Center"><Button Name="btnLogin"Width="80"Height="30"Command="{Binding LoginCommand}"CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}"Content="登录"IsDefault="True" /></WrapPanel></StackPanel></Grid>
</Window>
第十步:将View文件中的Main.XAML写好 然后写好ViewModel中的MainViewModel 最后创建两个UC
1.Main.XAML如下:
<Window x:Class="WPF练习12简单的项目.View.Main"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:WPF练习12简单的项目.View"xmlns:viewmodel="clr-namespace:WPF练习简单的项目12.ViewModel"d:DataContext="{d:DesignInstance Type=viewmodel:MainViewModel}"DataContext="{Binding Source={StaticResource Locator}, Path=Main}"mc:Ignorable="d"Title="Main" Height="450" Width="800"><Grid><Grid.RowDefinitions><RowDefinition Height="60" /><RowDefinition /></Grid.RowDefinitions><Grid VerticalAlignment="Center"><Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition Width="200" /></Grid.ColumnDefinitions><TextBlock Margin="10,0"VerticalAlignment="Center"FontSize="20"Text="任务列表管理MVVMLIGHT小案例" /><WrapPanel Grid.Column="1"HorizontalAlignment="Right"><TextBlock VerticalAlignment="Center"Text="当前用户:" /><TextBlock VerticalAlignment="Center"Text="{Binding CurrentUser.Account}" /><Button Width="80"Height="30"Margin="10,0"Command="{Binding LogoutCommand}"Content="退出" /></WrapPanel></Grid><Grid Grid.Row="1"><Grid.ColumnDefinitions><ColumnDefinition Width="160" /><ColumnDefinition /></Grid.ColumnDefinitions><StackPanel><Button Height="30"Margin="0,0,0,10"Command="{Binding ToggleCommand}"CommandParameter="user"Content="用户管理" /><Button Height="30"Margin="0,0,0,10"Command="{Binding ToggleCommand}"CommandParameter="todo"Content="任务管理" /></StackPanel><!-- ContentControl内容控件:充当一个控件容器,可以把UserControl.xaml放到此处,但不能放Page.xaml和Window.xaml文件。 --><ContentControl Grid.Column="1"Margin="10,0"Content="{Binding CurrentUserControl}" /></Grid></Grid>
</Window>
2.MainViewModel如下:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Windows;
using System.Windows.Controls;
using WPF练习12简单的项目.Contorls;
using WPF练习12简单的项目.Model;
using WPF练习12简单的项目.Tool;namespace WPF练习简单的项目12.ViewModel
{/// <summary>/// This class contains properties that the main View can data bind to./// <para>/// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel./// </para>/// <para>/// You can also use Blend to data bind with the tool's support./// </para>/// <para>/// See http://www.galasoft.ch/mvvm/// </para>/// </summary>public class MainViewModel : ViewModelBase{public MainViewModel(){currentUser = LoginInfo.CurrentUser;}private UserInfo currentUser;public UserInfo CurrentUser{get { return currentUser; }set { currentUser = value; RaisePropertyChanged(); }}private UserControl currentUserControl = new UCUserInfo();public UserControl CurrentUserControl{get { return currentUserControl; }set { currentUserControl = value; RaisePropertyChanged(); }}public RelayCommand<string> ToggleCommand{get{return new RelayCommand<string>((str) =>{switch (str){case "user":CurrentUserControl = new UCUserInfo();break;case "todo":CurrentUserControl = new UCTodo();break;default:CurrentUserControl = new UCUserInfo();break;}});}}public RelayCommand LogoutCommand{get{return new RelayCommand(() =>{Application.Current.Shutdown();});}}}
}
3.创建两个Contorls
UCUserInfo如下:
<UserControl x:Class="WPF练习12简单的项目.Contorls.UCUserInfo"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:WPF练习12简单的项目.Contorls"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid Background="White"><TextBlock Text="200" /></Grid>
</UserControl>
UCTodo如下:
<UserControl x:Class="WPF练习12简单的项目.Contorls.UCTodo"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:WPF练习12简单的项目.Contorls"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid Background="White"><TextBlock Text="100" /></Grid>
</UserControl>