WPF自定义Dialog模板,内容用不同的Page填充
因为审美的不同,就总有些奇奇怪怪的需求,使用框架自带的对话框已经无法满足了,这里记录一下我这边初步设计的对话框。别问为啥要用模板嵌套Page来做对话框,问就是不想写太多的窗体。。。。
模板窗体(XAML)
<Window x:Class="换成自己的程序集.DialogModel"
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:SCADA"
mc:Ignorable="d"
WindowStyle="None"
WindowStartupLocation="CenterScreen"
AllowsTransparency="True"
Background="#060931"
Foreground="White"
Title="DialogModel" Height="450" Width="600">
<Window.Resources>
<Style TargetType="DockPanel" x:Key="DockPanel">
<Setter Property="Background" >
<Setter.Value>
<ImageBrush ImageSource="/Images/top.png"/>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="StackPanel" x:Key="StackPanel">
<Setter Property="Background" >
<Setter.Value>
<ImageBrush ImageSource="/Images/tb_1.png"/>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Button" x:Key="Button">
<Setter Property="Background" >
<Setter.Value>
<ImageBrush ImageSource="/Images/btn1.png"/>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Foreground" Value="White"/>
</Style>
</Window.Resources>
<Grid x:Name="MyDialog">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<!--头部-->
<DockPanel x:Name="TOP" Style="{StaticResource DockPanel}" VerticalAlignment="Center" Height="60" Margin="0">
<TextBlock Text="{Binding DialogTitle}" Foreground="White" FontSize="20" VerticalAlignment="Center" Margin="20 0 0 0"/>
<WrapPanel VerticalAlignment="Center" HorizontalAlignment="Right">
<Button Height="20" Margin="5 0 5 0" Width="20" Padding="0" Background="Transparent" BorderBrush="Transparent" Foreground="White" x:Name="btnMin" Content="—" />
<Button Height="20" Margin="5 0 5 0" Width="20" Padding="0" Background="Transparent" BorderBrush="Transparent" Foreground="White" x:Name="btnMax" Content="❐" />
<Button Height="20" Margin="5 0 5 0" Width="20" Padding="0" Background="Transparent" BorderBrush="Transparent" Foreground="White" x:Name="btnClose" Content="╳"/>
</WrapPanel>
</DockPanel>
<!--内容-->
<Frame x:Name="MainFrame" Content="{Binding CurrentPage}" Grid.Row="1" NavigationUIVisibility="Hidden" BorderThickness="0"/>
<StackPanel Grid.Row="2" Style="{StaticResource StackPanel}" Visibility="{Binding ISVisible}">
<WrapPanel HorizontalAlignment="Right" >
<Button Style="{StaticResource Button}" Margin=" 0 10 20 10" Click="Confirm" Height="40" Width="120" Content="确定" />
<Button Style="{StaticResource Button}" Margin=" 0 10 10 10" Height="40" Width="120" Click="Cancel" Content="取消" />
</WrapPanel>
</StackPanel>
</Grid>
</Window>
模板窗体(cs)
/// <summary>
/// DialogModel.xaml 的交互逻辑
/// </summary>
public partial class DialogModel : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 消息通知方法
/// </summary>
/// <param name="propertyname"></param>
public void OnPropertyChanged([CallerMemberName] string propertyname = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
public DialogModel(Page page, string title,string Visible= "Visible")
{
InitializeComponent();
DataContext = this;
ISVisible = Visible;
CurrentPage = page;
DialogTitle = title;
btnMin.Click += (s, e) => { this.WindowState = WindowState.Minimized; };
btnMax.Click += (s, e) =>
{
if (this.WindowState == WindowState.Maximized)
this.WindowState = WindowState.Normal;
else
{
this.ResizeMode = ResizeMode.NoResize;
this.WindowState = WindowState.Maximized;
}
};
btnClose.Click += (s, e) => { this.Close(); };
TOP.MouseMove += (s, e) =>
{
if (e.LeftButton == MouseButtonState.Pressed)
{
this.DragMove();
}
};
}
#region 字段属性
private string title;
/// <summary>
/// 对话框标题
/// </summary>
public string DialogTitle
{
get { return title; }
set
{
title = value; OnPropertyChanged();
}
}
private Page currentpage;
public Page CurrentPage
{
get { return currentpage; }
set
{
currentpage = value;
OnPropertyChanged();
}
}
private string visible;
/// <summary>
/// 是否显示确认取消按钮组,Visible-显示,Collapsed隐藏
/// </summary>
public string ISVisible
{
get { return visible; }
set
{
visible = value; OnPropertyChanged();
}
}
#endregion
/// <summary>
/// 确认方法,此处未返回值是因为主要内容都在Page里面。业务逻辑都在Page中。你也可以放置在此处,具体如何传值得靠你自己
/// </summary>
private void Confirm(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
this.Close();
}
/// <summary>
/// 取消方法
/// </summary>
private void Cancel(object sender, RoutedEventArgs e)
{
this.Close();
}
}
Page(XAML,引用了materialDesign库,没有的话用你自己定义的page就好)
<Page x:Class="*****.Pages.User"
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:SCADA.Pages"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
Foreground="White"
d:DesignHeight="450" d:DesignWidth="400"
Title="User">
<Page.Resources>
<Style TargetType="Grid" x:Key="Grid">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/Images/tb_1.png"/>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Style="{StaticResource Grid}">
<StackPanel Margin="16" Width="300" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox Margin="10" Text="{Binding UserName}"
materialDesign:HintAssist.Hint="UserName"/>
<TextBox Margin="10" Text="{Binding Account}"
materialDesign:HintAssist.Hint="Account"/>
<TextBox Margin="10" Text="{Binding PassWord}"
materialDesign:HintAssist.Hint="PassWord"/>
<ComboBox x:Name="CurrentRole" SelectionChanged="RoleChange" Margin="10" materialDesign:ComboBoxAssist.MaxLength="2" DisplayMemberPath="Name" SelectedValuePath="Id" ItemsSource="{Binding Roles}" materialDesign:HintAssist.Hint="请选择用户角色" materialDesign:HintAssist.HintOpacity=".26" IsEditable="True">
</ComboBox>
<CheckBox Margin="10" Content="是否启用" IsChecked="{Binding IsActive}" />
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button Margin="0,8,8,0" Click="Confirm" Content="确认">
</Button>
<Button Margin="0,8,8,0" Click="Cancel" Content="取消">
</Button>
</StackPanel>
</StackPanel>
</Grid>
</Page>
Page(.cs)
/// <summary>
/// User.xaml 的交互逻辑
/// </summary>
public partial class User : Page, INotifyPropertyChanged
{
#region 通知
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 消息通知方法
/// </summary>
/// <param name="propertyname"></param>
public void OnPropertyChanged([CallerMemberName] string propertyname = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
#endregion
//这里的数据库用的EF,这里为啥这样写参考我前面的动态配置EF连接字符串的文章,此处可删
string SQLConnection = EFConnection.GetConnection(".", "sa", "123456", "XYDB", false);
public User()
{
InitializeComponent();
DataContext = this;//必要
//下面可删除
//Roles = new List<SelectRole>();
//Notice.MainUI = Application.Current.MainWindow;
//string config = SysConfig.GetConfig(SysConfig.PathBase, "SysSet");
//if (config != null)
//{
// var mo = JsonConvert.DeserializeObject<SystemSetModel>(config);
// SQLConnection = EFConnection.GetConnection(mo.DbIP, mo.DbAccount, mo.DbPassWord, mo.DbName, false);
//}
在此初始化所有角色
//using (var db = new DBEntities(SQLConnection))
//{
// var role = db.SysRoles.Where(m => m.IsActive).ToList();
// if (role != null && role.Count > 0)
// {
// foreach (var item in role)
// {
// SelectRole role1 = new SelectRole();
// role1.Id = item.Id;
// role1.Name = item.RoleName;
// Roles.Add(role1);
// }
// }
//}
}
#region 属性字段
private Guid id;
/// <summary>
/// Id
/// </summary>
public Guid Id
{
get { return id; }
set
{
id = value;
OnPropertyChanged();//参数可以不写,
}
}
private string username;
/// <summary>
///用户名
/// </summary>
public string UserName
{
get { return username; }
set
{
username = value; OnPropertyChanged();
}
}
private string account;
/// <summary>
///账号
/// </summary>
public string Account
{
get { return account; }
set
{
account = value; OnPropertyChanged();
}
}
private string password;
/// <summary>
///密码
/// </summary>
public string PassWord
{
get { return password; }
set
{
password = value; OnPropertyChanged();
}
}
private bool isactive;
/// <summary>
/// 状态
/// </summary>
public bool IsActive
{
get { return isactive; }
set
{
isactive = value;
OnPropertyChanged();
}
}
private bool isadd = true;
/// <summary>
/// 是否添加用户,用于辨别确认方法是添加还是编辑
/// </summary>
public bool IsAdd
{
get { return isadd; }
set
{
isadd = value;
OnPropertyChanged();
}
}
private Guid roleid;
/// <summary>
/// 选定的角色Id
/// </summary>
public Guid RoleId
{
get { return roleid; }
set
{
roleid = value;
OnPropertyChanged();//参数可以不写,
}
}
private List<SelectRole> roles;
/// <summary>
/// 可选的角色列表
/// </summary>
public List<SelectRole> Roles
{
get { return roles; }
set
{
roles = value;
OnPropertyChanged();
}
}
#endregion
/// <summary>
/// 添加/编辑
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Confirm(object sender, RoutedEventArgs e)
{
try
{
//下面的逻辑替换成自己的
//using (var db = new DBEntities(SQLConnection))
//{
// //添加用户
// if (IsAdd)
// {
// var Current = db.SysUsers.FirstOrDefault(m => m.Account == Account);
// if (Current == null)
// {
// SysUser user = new SysUser();
// user.Id = Guid.NewGuid();
// user.Name = UserName;
// user.Account = Account;
// user.PassWord = PassWord;
// user.IsActive = IsActive;
// user.CreateTime = DateTime.Now;
// user.LoginNum = 0;
// user.LoginTime = DateTime.Now;
// User_Role user_Role = new User_Role();
// user_Role.Id = Guid.NewGuid();
// user_Role.UserId = user.Id;
// user_Role.RoleId = RoleId;
// user.User_Role.Add(user_Role);
// db.SysUsers.Add(user);
// db.SaveChanges();
// Notice.SuccessNotification_Dark("添加成功", 20, 5);
// // 获取当前页面所在的窗体
// Window window = Window.GetWindow(this);
// // 检查是否找到窗体并关闭它
// if (window != null)
// {
// window.Close();
// }
// }
// else
// {
// Notice.WarningNotification_Dark($"当前用户账号已存在!", 20, 5);
// }
// }//编辑用户
// else
// {
// var Current = db.SysUsers.FirstOrDefault(m => m.Id != Id && m.Account == Account);
// if (Current == null)
// {
// var User = db.SysUsers.FirstOrDefault(m => m.Id == Id);
// if (User != null)
// {
// db.Entry(User).State = EntityState.Detached;//取消跟踪免得修改主键冲突
// User.Name = UserName;
// User.Account = Account;
// User.PassWord = PassWord;
// User.IsActive = IsActive;
// var role = User.User_Role.FirstOrDefault();
// if (role != null)//有配置角色
// {
// role.RoleId = RoleId;
// db.User_Role.Add(role);
// }
// else//无配置角色
// {
// User_Role userRole = new User_Role();
// userRole.Id = Guid.NewGuid();
// userRole.UserId = User.Id;
// userRole.RoleId = RoleId;
// db.User_Role.Add(userRole);
// }
// db.Entry(User).State = EntityState.Modified;
// db.SaveChanges();
// Notice.SuccessNotification_Dark("编辑成功", 20, 5);
// // 获取当前页面所在的窗体
// Window window = Window.GetWindow(this);
// // 检查是否找到窗体并关闭它
// if (window != null)
// {
// window.Close();
// }
// }
// else
// {
// Notice.FailtureNotification_Dark("未找到当前用户", 20, 5);
// return;
// }
// }
// else
// {
// Notice.WarningNotification_Dark($"当前账号已存在!", 20, 5);
// }
// }
//}
}
catch (Exception ex)
{
Notice.FailtureNotification_Dark($"失败:{ex.Message}", 20, 5);
}
}
/// <summary>
/// 取消
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e)
{
// 获取当前页面所在的窗体
Window window = Window.GetWindow(this);
// 检查是否找到窗体并关闭它
if (window != null)
{
window.Close();
}
}
private void RoleChange(object sender, SelectionChangedEventArgs e)
{
RoleId=(Guid)CurrentRole.SelectedValue;
}
}
public class SelectRole
{
public Guid Id { get; set; }
public string Name { set; get; }
}
使用方法(供参考):
添加用户:
User user = new User();
DialogModel dialog = new DialogModel(user, "添加用户", "Collapsed");
dialog.ShowDialog();
编辑用户(需要赋值):
/// <summary>
/// DataGird的自定义操作栏的编辑按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void UserEdit(object sender, RoutedEventArgs e)
{
UserInfoDto userInfo = new UserInfoDto();
var co = (Control)sender;
userInfo = (UserInfoDto)co.DataContext;//获取当前行数据
User user = new User();//实例化Page
user.IsAdd = false;//标识是编辑
user.Id = userInfo.Id;//将当前行信息给到Page,绑定到控件
user.UserName = userInfo.Name;
user.Account = userInfo.Account;
user.PassWord = userInfo.PassWord;
user.IsActive = userInfo.IsActive;
user.RoleId = userInfo.RoleId;
for (int i = 0; i < user.Roles.Count; i++)
{
if (user.Roles[i].Id == userInfo.RoleId)
{
if (user.Roles.Count > 1)
{
user.Roles.Remove(user.Roles[i]);
user.Roles.Insert(0, user.Roles[i]);
}
}
}
DialogModel dialog = new DialogModel(user, "编辑用户", "Collapsed");
dialog.ShowDialog();
}
最终结果(用到的背景图片啥的我就不贴了,毕竟我觉得不太好看):