c# WPF Prism 对话服务
1.登录界面(LoginViewModel.xaml)
<!--UserrControl标签内添加-->
<UserControl
xmlns:p="http://prismlibrary.com/"
Focusable="True">
<p:Dialog.WindowStyle>
<Style TargetType="Window">
<Setter Property="WindowStyle" Value="ToolWindow" />
<Setter Property="Width" Value="400" />
<Setter Property="Height" Value="250" />
<Setter Property="p:Dialog.WindowStartupLocation" Value="CenterScreen" />
</Style>
</p:Dialog.WindowStyle>
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<WrapPanel Margin="0,0,0,10">
<Label Content="账号:" />
<TextBox
Width="120"
VerticalContentAlignment="Center"
Text="{Binding Account}" />
</WrapPanel>
<WrapPanel Margin="0,0,0,20">
<Label Content="密码:" />
<TextBox
Width="120"
VerticalContentAlignment="Center"
Text="{Binding PassWord}" />
</WrapPanel>
<WrapPanel HorizontalAlignment="Center">
<Button
Width="80"
Height="30"
Command="{Binding LoginCommand}"
Content="登录" />
</WrapPanel>
</StackPanel>
</Grid>
</UserControl>
2.登录界面视图模型(LoginViewModel)
public class LoginViewModel : BindableBase, IDialogAware
{
public string Title => "登录窗体";
public event Action<IDialogResult> RequestClose;
public bool CanCloseDialog() { return true;}
public void OnDialogClosed(){ }
public void OnDialogOpened(IDialogParameters parameters){ }
private string account;
public string Account
{
get { return account; }
set { SetProperty(ref account, value); }
}
private string passWord;
public string PassWord
{
get { return passWord; }
set { SetProperty(ref passWord, value); }
}
public DelegateCommand LoginCommand
{
get
{
return new DelegateCommand(() =>
{
// 登录逻辑
if(Account == "花花" && PassWord == "123456")
{
DialogParameters parameters = new DialogParameters()
{
{"account",Account },
{"passWord",PassWord },
};
RequestClose?.Invoke(new DialogResult(ButtonResult.OK,parameters));
}
});
}
}
}
3.主页面视图(MainWindow.xaml)
<Window
x:Class="对话服务.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="700"
Height="400"
prism:ViewModelLocator.AutoWireViewModel="True"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Background="#2F4F4F">
<TextBlock
VerticalAlignment="Center"
FontSize="25"
Foreground="White"
Text="XXX管理系统" />
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Background="#2F4F4F">
<Button
Height="30"
Command="{Binding TogglePageCommand}"
CommandParameter="PageA"
Content="PageA" />
<Button
Height="30"
Margin="0,10,0,0"
Command="{Binding TogglePageCommand}"
CommandParameter="PageB"
Content="PageB" />
<Button
Height="30"
Margin="0,10,0,0"
Command="{Binding TogglePageCommand}"
CommandParameter="PageC"
Content="PageC" />
</StackPanel>
<ContentControl Grid.Column="1" prism:RegionManager.RegionName="ContentRegion" />
</Grid>
</Grid>
</Window>
4.主页面视图模型 (MainWindowViewModel)
public class MainWindowViewModel : BindableBase
{
private readonly IRegionManager regionManager;
public MainWindowViewModel(IRegionManager regionManager)
{
this.regionManager = regionManager;
}
private string _title = "对话服务";
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public DelegateCommand<string> TogglePageCommand => new DelegateCommand<string>((page) =>
{
this.regionManager.RequestNavigate("ContentRegion",page);
});
}
5.App.xaml.cs
public partial class App
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void OnInitialized()
{
// 对话服务本身也受ioc管理
IDialogService dialogService = Container.Resolve<IDialogService>();//从ico容器中取对话服务
dialogService.ShowDialog("Login", (dr) =>
{
if(dr.Result == ButtonResult.OK)
{
if(dr.Parameters.ContainsKey("account") && dr.Parameters.ContainsKey("passWord"))
{
string acc = dr.Parameters.GetValue<string>("account");
string pwd = dr.Parameters.GetValue<string>("passWord");
base.OnInitialized();
}
}
else Current.Shutdown();
});
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 视图注册成可以导航的视图
// 导航视图模型要求:继承 BindableBase
containerRegistry.RegisterForNavigation<PageA, PageAViewModel>();
containerRegistry.RegisterForNavigation<PageB, PageBViewModel>();
containerRegistry.RegisterForNavigation<PageC, PageCViewModel>();
// 视图注册成对话框
// 对话框视图模型要求:必须继承BindableBase, 且实现IDialogAware
containerRegistry.RegisterDialog<PageAEdit, PageAEditViewModel>();
containerRegistry.RegisterDialog<Login,LoginViewModel>();
}
}
6.页面PageA视图(PageA.xaml)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel>
<Button
Width="100"
Height="40"
Command="{Binding AddCommand}"
Content="添加" />
</StackPanel>
<DataGrid
Grid.Row="1"
AutoGenerateColumns="False"
IsReadOnly="True"
ItemsSource="{Binding Students}">
<DataGrid.Columns>
<DataGridTextColumn
Width="*"
Binding="{Binding Id}"
Header="编号" />
<DataGridTextColumn
Width="*"
Binding="{Binding Name}"
Header="姓名" />
<DataGridTextColumn
Width="*"
Binding="{Binding Age}"
Header="年龄" />
<DataGridTemplateColumn Width="2*" Header="操作">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<WrapPanel>
<Button
Width="50"
Margin="0,0,10,0"
Content="删除" />
<Button
Width="50"
Margin="0,0,10,0"
Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
CommandParameter="{Binding Id}"
Content="编辑" />
</WrapPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
7.页面PageA视图模型(PageAViewModel)
public class PageAViewModel : BindableBase
{
private readonly IDialogService dialogService; //对话服务
public PageAViewModel(IDialogService dialogService)
{
Students = Data.Students;
this.dialogService = dialogService;
}
private List<Student> students;
public List<Student> Students
{
get => students;
set => SetProperty(ref students, value);
}
public DelegateCommand<object> EditCommand
{
get
{
return new DelegateCommand<object>((id) =>
{
DialogParameters parameters = new DialogParameters() { { "stuId",id} } ;
// 参数1:对话框名称
// 参数2:向对话框传递的参数
// 参数3:对话的回调函数
this.dialogService.ShowDialog("PageAEdit", parameters, (dr) =>
{
if(dr.Result == ButtonResult.OK)
{
List<Student> stus = new List<Student>();
foreach (Student student in Data.Students)
{
stus.Add(student);
}
Students = stus;
}
});
});
}
}
public DelegateCommand AddCommand
{
get
{
return new DelegateCommand(() =>
{
this.dialogService.ShowDialog("PageAEdit", null, (dr) =>
{
if(dr.Result == ButtonResult.OK)
{
// 重新刷新DataGrid
List<Student> stus = new List<Student>();
foreach(var student in Data.Students)
{
stus.Add(student);
}
Students = stus;
}
});
});
}
}
}
8.页面PageA所需数据源Model
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
public class Data
{
public static List<Student> Students = new List<Student>()
{
new Student(){Id=1,Name="张三",Age=18},
new Student(){Id=2,Name="李四",Age=20},
new Student(){Id=3,Name="王五",Age=22},
new Student(){Id=4,Name="赵六",Age=24}
};
}
9.页面PageA的编辑(添加)视图(PageAEdit)
<!--UserrControl标签内添加-->
<UserControl
xmlns:prism="http://prismlibrary.com/">
<prism:Dialog.WindowStyle>
<Style TargetType="Window">
<Setter Property="Width" Value="400" />
<Setter Property="Height" Value="250" />
<Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen" />
<Setter Property="ResizeMode" Value="NoResize" />
</Style>
</prism:Dialog.WindowStyle>
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<WrapPanel Margin="0,0,0,10">
<Label Content="姓名:" />
<TextBox
Width="100"
VerticalContentAlignment="Center"
Text="{Binding OneStudent.Name}" />
</WrapPanel>
<WrapPanel Margin="0,0,0,20">
<Label Content="年龄:" />
<TextBox
Width="100"
VerticalContentAlignment="Center"
Text="{Binding OneStudent.Age}" />
</WrapPanel>
<WrapPanel HorizontalAlignment="Center">
<Button
Width="60"
Height="30"
Margin="0,0,20,0"
Command="{Binding OKCancelCommand}"
CommandParameter="OK"
Content="确定" />
<Button
Width="60"
Height="30"
Command="{Binding OKCancelCommand}"
CommandParameter="Cancel"
Content="取消" />
</WrapPanel>
</StackPanel>
</Grid>
</UserControl>
10.编辑(添加)页面的视图模型(PageAEditViewModel)
public class PageAEditViewModel : BindableBase, IDialogAware
{
//对话框的标题
public string Title => "编辑";
//请求关闭的事件:关闭对话框时执行的事件
public event Action<IDialogResult> RequestClose;
#region IDialogAware接口
//控制对话框是否能关闭
public bool CanCloseDialog(){ return true;}
//对话框关闭时执行(两种情况:关闭 取消)
public void OnDialogClosed(){ }
//对话框打开时执行
public void OnDialogOpened(IDialogParameters parameters)
{
if (parameters.ContainsKey("stuId"))
{
IsAdd = false;
StuId = parameters.GetValue<int>("stuId");
OneStudent = Data.Students.AsQueryable().Where(s => s.Id == StuId).FirstOrDefault();
}
else IsAdd = true;
}
#endregion
private Student oneStudent = new Student();
public Student OneStudent
{
get { return oneStudent; }
set { SetProperty(ref oneStudent, value); }
}
private int stuId;
public int StuId
{
get { return stuId; }
set { SetProperty(ref stuId, value); }
}
private bool isAdd;
public bool IsAdd
{
get { return isAdd; }
set { SetProperty(ref isAdd, value); }
}
public DelegateCommand<string> OKCancelCommand
{
get
{
return new DelegateCommand<string>((flag) =>
{
if (IsAdd) // 添加
{
if(flag == "OK")// 确定
{
Student lastStudent = Data.Students[Data.Students.Count - 1];
Student stu = new Student()
{
Id = lastStudent.Id + 1,
Name = OneStudent.Name,
Age = OneStudent.Age,
};
Data.Students.Add(stu);
RequestClose?.Invoke(new DialogResult(ButtonResult.OK));
return;
}
RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
}
else // 编辑
{
if(flag == "OK")
{
int index = Data.Students.FindIndex((s) => { return s.Id == StuId; });
Data.Students[index] = OneStudent;
RequestClose?.Invoke(new DialogResult(ButtonResult.OK));
return;
}
RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
}
});
}
}
}
11.页面PageB 和页面PageC的视图
<Grid>
<Label Content="页面B" />
</Grid>
<Grid>
<Label Content="页面C" />
</Grid>