用C#在mvvm设计模式下,用IHostedService设计登陆跳转窗口程序,请给出完整实例代码
时间: 2024-05-10 14:19:02 浏览: 212
以下是一个简单的基于MVVM设计模式和IHostedService的登录跳转窗口程序的示例代码:
MainWindow.xaml:
```xaml
<Window x:Class="LoginRedirectApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Login Redirect App" Height="350" Width="525">
<Grid>
<ContentControl Content="{Binding CurrentViewModel}" />
</Grid>
</Window>
```
App.xaml.cs:
```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
using System.Windows;
namespace LoginRedirectApp
{
public partial class App : Application
{
private readonly IHost _host;
public App()
{
_host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
services.AddSingleton<MainWindow>();
services.AddSingleton<LoginViewModel>();
services.AddSingleton<HomeViewModel>();
services.AddSingleton<IHostedService, LoginRedirectService>();
})
.Build();
}
protected override async void OnStartup(StartupEventArgs e)
{
await _host.StartAsync();
var mainWindow = _host.Services.GetService<MainWindow>();
mainWindow.Show();
base.OnStartup(e);
}
protected override async void OnExit(ExitEventArgs e)
{
using var scope = _host.Services.CreateScope();
var hostedServices = scope.ServiceProvider.GetServices<IHostedService>();
foreach (var service in hostedServices)
{
await service.StopAsync();
}
await _host.StopAsync();
base.OnExit(e);
}
}
}
```
LoginViewModel.cs:
```csharp
using System;
using System.Windows.Input;
namespace LoginRedirectApp
{
public class LoginViewModel : ViewModelBase
{
private readonly ILoginService _loginService;
private readonly IRedirectService _redirectService;
private string _username;
public string Username
{
get => _username;
set => SetProperty(ref _username, value);
}
private string _password;
public string Password
{
get => _password;
set => SetProperty(ref _password, value);
}
public ICommand LoginCommand { get; }
public LoginViewModel(ILoginService loginService, IRedirectService redirectService)
{
_loginService = loginService;
_redirectService = redirectService;
LoginCommand = new RelayCommand(Login, CanLogin);
}
private bool CanLogin()
{
return !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password);
}
private async void Login()
{
try
{
var result = await _loginService.LoginAsync(Username, Password);
if (result)
{
_redirectService.RedirectToHome();
}
else
{
// handle login failure
}
}
catch (Exception ex)
{
// handle login exception
}
}
}
}
```
HomeViewModel.cs:
```csharp
namespace LoginRedirectApp
{
public class HomeViewModel : ViewModelBase
{
// add properties and methods for home view model here
}
}
```
LoginRedirectService.cs:
```csharp
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace LoginRedirectApp
{
public class LoginRedirectService : IHostedService
{
private readonly IRedirectService _redirectService;
private readonly ILoginService _loginService;
private readonly MainWindow _mainWindow;
private readonly LoginViewModel _loginViewModel;
private readonly HomeViewModel _homeViewModel;
public LoginRedirectService(IRedirectService redirectService,
ILoginService loginService,
MainWindow mainWindow,
LoginViewModel loginViewModel,
HomeViewModel homeViewModel)
{
_redirectService = redirectService;
_loginService = loginService;
_mainWindow = mainWindow;
_loginViewModel = loginViewModel;
_homeViewModel = homeViewModel;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_redirectService.RedirectToLogin();
_mainWindow.DataContext = _loginViewModel;
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
public interface IRedirectService
{
void RedirectToLogin();
void RedirectToHome();
}
public class RedirectService : IRedirectService
{
private readonly MainWindow _mainWindow;
private readonly LoginViewModel _loginViewModel;
private readonly HomeViewModel _homeViewModel;
public RedirectService(MainWindow mainWindow,
LoginViewModel loginViewModel,
HomeViewModel homeViewModel)
{
_mainWindow = mainWindow;
_loginViewModel = loginViewModel;
_homeViewModel = homeViewModel;
}
public void RedirectToLogin()
{
_mainWindow.DataContext = _loginViewModel;
}
public void RedirectToHome()
{
_mainWindow.DataContext = _homeViewModel;
}
}
public interface ILoginService
{
Task<bool> LoginAsync(string username, string password);
}
public class LoginService : ILoginService
{
public async Task<bool> LoginAsync(string username, string password)
{
// add login logic here, return true if login is successful
return await Task.FromResult(true);
}
}
}
```
ViewModelBase.cs:
```csharp
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace LoginRedirectApp
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (!Equals(field, value))
{
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
```
RelayCommand.cs:
```csharp
using System;
using System.Windows.Input;
namespace LoginRedirectApp
{
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public RelayCommand(Action execute, Func<bool> canExecute = null)
{
_execute = execute;
_canExecute = canExecute ?? (() => true);
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object parameter)
{
return _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
}
}
```
在这个示例中,我们使用了三个视图模型:`LoginViewModel`,`HomeViewModel`和`ViewModelBase`,其中`LoginViewModel`和`HomeViewModel`继承自`ViewModelBase`。`LoginViewModel`用于处理登录逻辑,`HomeViewModel`用于处理主页逻辑。`ViewModelBase`实现了`INotifyPropertyChanged`接口,用于在属性更改时通知视图。
我们还使用了三个服务:`ILoginService`,`IRedirectService`和`LoginRedirectService`。`ILoginService`用于处理登录逻辑,`IRedirectService`用于处理跳转逻辑,`LoginRedirectService`实现了`IHostedService`接口,用于在应用程序启动时将用户重定向到登录界面。
最后,我们使用了`RelayCommand`类实现了`ICommand`接口,以便我们可以在视图中使用命令。
阅读全文