WPF应用程序(.NET Core) 列表数据编辑(弹出层形式 反填+修改)

 

WPF应用程序(.NET Core)  列表数据编辑(弹出层形式反填+修改)

一、列表操作列中加入编辑按钮--并绑定事件

  1、   .xaml文件设计

在WPF中如何使用RelativeSource绑定

复制代码
1  <!--  CommandParameter="{Binding}" 代表把当前行的对象作为参数传递  -->
2                                     <!--  RelativeSource进行绑定,这种办法的意思是指当前元素和绑定源的位置关系  -->
3                                     <!--  AncestorType指定绑定源为某个父元素  -->
4                                     <Button
5                                         Command="{Binding Path=DataContext.EditOpenCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
6                                         CommandParameter="{Binding}"
7                                         Content="编辑" />
Button
复制代码

 

    以下可借助参考别人的,不全一样 :    Prism之对话服务(DialogService)

  2、创建用于在点击列表编辑按钮后触发实现显示dialog接口  (接口名字后面改成了IDialogShow)

复制代码
 1 /// <summary>
 2     /// 弹出层接口, 用于弹出 弹出层
 3     /// </summary>
 4     public interface IDialogHostService
 5     {
 6         /// <summary>
 7         /// 弹出弹出层窗口
 8         /// </summary>
 9         /// <param name="name">弹出层页面的名</param>
10         /// <param name="parameters">给弹出层的页面传递的参数</param>
11         /// <param name="dialogHostName">弹出层的控件的Identifier属性的值  默认使用Home.xaml视图里的 DialogHost 控件</param>
12         /// <returns></returns>
13         Task<IDialogResult> ShowDialog(string name, IDialogParameters parameters, string dialogHostName = "RootDialog");
14     }
IDialogHostService
复制代码

 

  3、   .cs触发事件编辑(笔记涉及IDialogHostServer接口名字后面改成了IDialogShow)

复制代码
 1         private readonly IDialogHostService _IDialogHostService;
 2         /// <summary>
 3         /// 列表操作列编辑委托
 4         /// </summary>
 5         /// 编辑按钮
 6         public DelegateCommand<LoginUser> EditOpenCommand { get; private set; }
 7         public UserManagerViewModel(IDialogHostService _IDialogHostServices, IEventAggregator aggregators, IRegionManager regionManager) : base(aggregators)
 8         {
 9             this.regionManager = regionManager;
10             EditOpenCommand = new DelegateCommand<LoginUser>(OpenUpdDialog);
11             //依赖注入dialog服务,用于弹出弹出层
12             _IDialogHostService = _IDialogHostServices;
13         }
14         /// <summary>
15         /// 打开编辑页页dialog的方法
16         /// </summary>
17         /// <param name="LoginUser">传递的参数</param>
18         public async void OpenUpdDialog(LoginUser u)
19         {
20             //存放dialog初始的数据--反填
21             DialogParameters param = new DialogParameters();
22             if (u != null)
23             {
24                 param.Add("UserValue", u);
25             }
26             //弹出用户修改dialog           UserUpd--修改页名(.xaml文件名)
27             var dialogResult = await _IDialogHostService.ShowDialog("UserUpd", param);
28         }
.cs文件
复制代码

 

4、创建在弹出diaolg后,弹出层中的点击事件的对应实现接口

复制代码
 1 /// <summary>
 2     /// 定义弹出窗口实现方法的接口
 3     /// </summary>
 4     public interface IDialogOperate
 5     {
 6 
 7         /// <summary>
 8         /// 窗体名称
 9         /// </summary>
10         string WindowName { get; set; }
11 
12         /// <summary>
13         /// 打开过程中执行
14         /// </summary>
15         /// <param name="parameters">参数</param>
16         void OnDialogOpend(IDialogParameters parameters);
17 
18         /// <summary>
19         /// 确定命令
20         /// </summary>
21         DelegateCommand SaveCommand { get; set; }
22 
23         /// <summary>
24         /// 取消命令
25         /// </summary>
26         DelegateCommand CancelCommand { get; set; }
27     }
IDialogOperate
复制代码

 

5、创建DialogShow.cs类继承并实现上述IDialogShow接口类方法   

 

复制代码
 1 public class DialogShow : DialogService, IDialogShow
 2     {
 3         //prism Ioc 容器
 4         private readonly IContainerExtension containerExtension;
 5 
 6         /// <summary>
 7         /// 注入ioc容器
 8         /// </summary>
 9         /// <param name="containerExtension"></param>
10         public DialogShow(IContainerExtension containerExtension) : base(containerExtension)
11         {
12             this.containerExtension = containerExtension;
13         }
14         /// <summary>
15         /// 弹出弹出层窗口
16         /// </summary>
17         /// <param name="name">弹出层页面的类名</param>
18         /// <param name="parameters">给弹出层的页面传递的参数</param>
19         /// <param name="dialogHostName">弹出层的 Identifier属性的key</param>
20         /// <returns></returns>
21         /// <exception cref="NullReferenceException"></exception>
22 
23         public async Task<IDialogResult> ShowDialog(string name, IDialogParameters parameters, string dialogHostName = "RootDialog")
24         {
25             if (parameters == null)
26                 parameters = new DialogParameters();
27 
28             //在App.xaml中注入的IOC(prism自带的IOC)
29             //从容器当中取出弹出窗口的实例根据弹出层的类名   根据名称获取视图
30             var content = containerExtension.Resolve<object>(name);
31             //判断是否弹出层这个容器注入到了IOC中  有没有APP。xaml注册
32             if (content == null)
33             {
34                 throw new NullReferenceException("IOC容器中没有执行弹出层要弹出的窗体");
35             }
36             //验证实例的有效性  验证弹出层类型是否是WPF的元素  必须是FrameworkElement类型
37             //是则把他赋值给dialogContent
38             if (!(content is FrameworkElement dialogContent))
39                 throw new NullReferenceException("弹出层的 content 必须是 FrameworkElement 类型");
40 
41             //是则把他转化(赋值)为view
42             if (dialogContent is FrameworkElement view && view.DataContext is null && ViewModelLocator.GetAutoWireViewModel(view) is null)
43                 ViewModelLocator.SetAutoWireViewModel(view, true);
44 
45             //如果没有继承IDialogShow接口
46             if (!(dialogContent.DataContext is IDialogOperate viewModel))
47                 throw new NullReferenceException("弹出层 ViewModel 必须继承接口 IDialogOpenWindow ");
48 
49             //赋值dialog名
50             viewModel.WindowName = dialogHostName;
51 
52             //一个委托
53             DialogOpenedEventHandler eventHandler = (sender, eventArgs) =>
54             {
55                 if (viewModel is IDialogOperate aware)
56                 {
57                     //调用打开过程中执行方法
58                     aware.OnDialogOpend(parameters);
59                 }
60                 eventArgs.Session.UpdateContent(content);
61             };
62             return (IDialogResult)await DialogHost.Show(dialogContent, viewModel.WindowName, eventHandler);
63 
64         }
65     }
DialogShow
复制代码

 

5、App.Xaml文件prism IOC容器注册

 

6、创建弹出层页面窗体(右键添加用户控件)和其ViewModel类   App.xaml文件中映射建立联系

 

7、设计xaml页面布局(新建一个弹出层页面)

 

复制代码
<UserControl
    x:Class="GroupThreeObject02WindosWPF.View.SystemBase.User.UserUpd"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Validation="clr-namespace:GroupThreeObject02WindosWPF.Common.Validation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
    xmlns:local="clr-namespace:GroupThreeObject02WindosWPF.View.SystemBase.User"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
    xmlns:passWord="clr-namespace:GroupThreeObject02WindosWPF.Common.Extensions"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">
    <!--  申明一个用户控件资源  -->
    <UserControl.Resources />
    <md:DialogHost
        x:Name="DialogHost"
        DialogTheme="Inherit"
        Identifier="Root">
        <Grid Background="White">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock
                Grid.Row="0"
                Padding="20,10"
                FontSize="20"
                FontWeight="Bold"
                Text="{Binding DialogTitleName}" />
            <DockPanel Grid.Row="1" LastChildFill="False">

                <StackPanel
                    Margin="0,10,10,10"
                    DockPanel.Dock="Top"
                    Orientation="Horizontal">
                    <StackPanel.Style>
                        <!--  申明一个触发器, 触发器关联的空间类型是 StackPanel  -->
                        <Style TargetType="StackPanel">
                            <Style.Triggers>
                                <!--  触发器为data触发器 如果 IsUpdate 是true  -->
                                <DataTrigger Binding="{Binding IsUpdate}" Value="true">
                                    <!--  StackPanel 显示  -->
                                    <Setter Property="Visibility" Value="Visible" />

                                </DataTrigger>
                                <!--  触发器为data触发器 如果 IsUpdate 是false  -->
                                <DataTrigger Binding="{Binding IsUpdate}" Value="false">
                                    <!--  StackPanel 不显示  -->
                                    <Setter Property="Visibility" Value="Collapsed" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </StackPanel.Style>
                    <TextBox
                        Width="200"
                        Margin="0,0,10,0"
                        VerticalAlignment="Center"
                        materialDesign:HintAssist.Hint="用户名"
                        Style="{StaticResource MaterialDesignFilledTextBox}">
                        <TextBox.Text>
                            <Binding Path="user_name" UpdateSourceTrigger="PropertyChanged">
                                <Binding.ValidationRules>
                                    <Validation:NotEmptyValidationRule ValidatesOnTargetUpdated="True" />
                                </Binding.ValidationRules>
                            </Binding>
                        </TextBox.Text>
                    </TextBox>
                    <TextBox
                        Width="200"
                        VerticalAlignment="Center"
                        materialDesign:HintAssist.Hint="用户全名"
                        Style="{StaticResource MaterialDesignFilledTextBox}"
                        Text="{Binding user_full_name}" />
                </StackPanel>
                <StackPanel
                    Margin="0,10,10,10"
                    DockPanel.Dock="Top"
                    Orientation="Horizontal">
                    <StackPanel.Style>
                        <!--  申明一个触发器, 触发器关联的空间类型是 StackPanel  -->
                        <Style TargetType="StackPanel">
                            <Style.Triggers>
                                <!--  触发器为data触发器 如果 IsUpdate 是true  -->
                                <DataTrigger Binding="{Binding IsUpdatePwd}" Value="true">
                                    <!--  StackPanel 显示  -->
                                    <Setter Property="Visibility" Value="Visible" />

                                </DataTrigger>
                                <!--  触发器为data触发器 如果 IsUpdate 是false  -->
                                <DataTrigger Binding="{Binding IsUpdatePwd}" Value="false">
                                    <!--  StackPanel 不显示  -->
                                    <Setter Property="Visibility" Value="Collapsed" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </StackPanel.Style>
                    <PasswordBox
                        Width="200"
                        Margin="0,0,10,0"
                        VerticalAlignment="Center"
                        materialDesign:HintAssist.Hint="密码"
                        passWord:PassWordExtension.Password="{Binding pwd, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                        Style="{StaticResource MaterialDesignFilledPasswordBox}">
                        <i:Interaction.Behaviors>
                            <passWord:PasswordBehavior />
                        </i:Interaction.Behaviors>
                    </PasswordBox>
                    <PasswordBox
                        Width="200"
                        VerticalAlignment="Center"
                        materialDesign:HintAssist.Hint="验证密码"
                        passWord:PassWordExtension.Password="{Binding VPassWord, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                        Style="{StaticResource MaterialDesignFilledPasswordBox}">
                        <i:Interaction.Behaviors>
                            <passWord:PasswordBehavior />
                        </i:Interaction.Behaviors>
                    </PasswordBox>

                </StackPanel>

            </DockPanel>
            <StackPanel
                Grid.Row="2"
                Margin="10"
                HorizontalAlignment="Right"
                Orientation="Horizontal">
                <Button
                    Margin="0,0,10,0"
                    Command="{Binding CancelCommand}"
                    Content="取消"
                    Style="{StaticResource MaterialDesignOutlinedButton}" />
                <Button Command="{Binding SaveCommand}" Content="确定" />
            </StackPanel>
        </Grid>
    </md:DialogHost>
</UserControl>
xaml
复制代码

 

 

 8、编写.CS文件实现对应功能

复制代码
using GroupThreeObject02DBModel;
using GroupThreeObject02ViewModel.Common;
using GroupThreeObject02WindosWPF.Common;
using GroupThreeObject02WindosWPF.Common.Extensions;
using GroupThreeObject02WindosWPF.Common.MyDialog;
using GroupThreeObject02WindosWPF.Service.Login;
using MaterialDesignThemes.Wpf;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GroupThreeObject02WindosWPF.View.SystemBase.User
{
    internal class UserUpdViewModel : BaseViewModel, IDialogOperate
    {
        private readonly LoginUserInfoService _LoginUserInfoService;
        private readonly IRegionManager regionManager;
        public string WindowName { get; set; }
        //依赖注入

        public UserUpdViewModel(IEventAggregator aggregators, LoginUserInfoService _LoginUserInfoServices, IRegionManager regionManager) : base(aggregators)
        {
            _LoginUserInfoService = _LoginUserInfoServices;
            SaveCommand = new DelegateCommand(Save);
            CancelCommand = new DelegateCommand(Cancel);
            //regionManager = regionManager;//跳转页面
        }
        private bool _isUpdate;
        /// <summary>
        /// 控制修改用户名那个容器StackPanel的触发器  控制StackPanel容器是否显示  true是显示   false 是不显示
        /// </summary>
        public bool IsUpdate
        {
            get
            {
                return _isUpdate;
            }
        }
        private bool _IsUpdatePwd;
        /// <summary>
        /// 控制修改密码容器StackPanel的触发器  控制StackPanel容器是否显示  true是显示   false 是不显示  
        /// </summary>
        public bool IsUpdatePwd
        {
            get
            {
                return _IsUpdatePwd;
            }
        }
        /// <summary>
        /// 弹出层dialog文本标题
        /// </summary>
        private string _DialogTitleName;
        public string DialogTitleName
        {
            get
            {
                return _DialogTitleName;
            }
        }

        public string userName;
        public string password;
        public string _user_full_name;
        /// <summary>
        /// 用户名--通过wpf页面获取用户名--双向绑定
        /// </summary>
        public string user_name
        {
            get { return userName; }
            set
            {
                userName = value;
                RaisePropertyChanged();  //双向绑定通知  继承BindableBase基类
            }
        }
        /// <summary>
        /// 用户全名
        /// </summary>
        public string user_full_name
        {
            get { return _user_full_name; }
            set { _user_full_name = value; RaisePropertyChanged(); }
        }  /// <summary>
           /// 密码
           /// </summary>
        public string pwd
        {
            get { return password; }
            set { password = value; RaisePropertyChanged(); }
        }

        public string _vPassWord;
        /// <summary>
        /// 验证密码
        /// </summary>
        public string VPassWord
        {
            get => _vPassWord;
            set
            {
                _vPassWord = value;
                RaisePropertyChanged();
            }
        }
        //获取diaLog传过来的对象--最后用于修改
        private LoginUser adminUser;

        /// <summary>
        /// 打开弹出层页面执行的方法--赋值,判断打开哪个页面
        /// </summary>
        /// <param name="parameters">传递用户对象</param>
        public void OnDialogOpend(IDialogParameters parameters)
        {
            //根据弹出层传过来的值的key值进行判断当下是编辑的用户信息还是密码
            if (parameters.ContainsKey("UserValue"))
            {
                //取出来传的值,实现反填
                adminUser = parameters.GetValue<LoginUser>("UserValue");
                userName = adminUser.user_name;
                _user_full_name = adminUser.user_full_name;
                _isUpdate = true;
                _IsUpdatePwd = false;
                _DialogTitleName = "信息修改";

            }
            //修改密码
            if (parameters.ContainsKey("PwdValue"))
            {
                //取出来传的值,实现反填
                adminUser = parameters.GetValue<LoginUser>("PwdValue");
                password = adminUser.pwd;
                _isUpdate = false;
                _IsUpdatePwd = true;
                _DialogTitleName = "密码修改";

            }
        }


        /// <summary>
        /// 保存事件委托
        /// </summary>
        public DelegateCommand SaveCommand { get; set; }
        /// <summary>
        /// 取消事件委托
        /// </summary>
        public DelegateCommand CancelCommand { get; set; }

        /// <summary>
        /// 取消,关闭弹出窗
        /// </summary>
        private void Cancel()
        {
            if (DialogHost.IsDialogOpen(WindowName))
                DialogHost.Close(WindowName, new DialogResult(ButtonResult.No)); //取消返回NO告诉操作结束
        }

        /// <summary>
        /// 确定保存
        /// </summary>
        private async void Save()
        {
            //if (string.IsNullOrWhiteSpace(Model.Title) ||
            //    string.IsNullOrWhiteSpace(model.Content)) return;

            if (DialogHost.IsDialogOpen(WindowName))
            {
                try
                {
                    WaitFor(true);

                    await Task.Delay(2000);

                    //DialogParameters param = new DialogParameters();
                    //param.Add("Value", AdminUser);

                    //调用api修改保存
                    if (_isUpdate)
                    {
                        //代表修改用户信息
                        LoginUser l = new LoginUser() { Lid = adminUser.Lid, user_name = user_name, user_full_name = user_full_name };
                        var res = _LoginUserInfoService.UpdUser(l);
                        aggregator.SendMessage(res.mess);
                        DialogHost.Close(WindowName);
                        // 默认跳转到欢迎起始页
                        //regionManager.Regions[PrismAreaName.MainViewRegionName].RequestNavigate("UserManager");
                      
                    }
                    if (_IsUpdatePwd)
                    {
                        //代表修改密码
                        LoginUser l = new LoginUser() { Lid = adminUser.Lid, pwd = pwd };
                        var res = _LoginUserInfoService.UpdPwd(l);
                        aggregator.SendMessage(res.mess);
                        DialogHost.Close(WindowName);
                        //刷新显示页
                    }

                    //DialogHost.Close(WindowName, new DialogResult(ButtonResult.OK, param));

                }
                catch { }
                finally
                {
                    WaitFor(false);
                }

            }
        }

    }
}
ViewModel.cs
复制代码

 

 

  8、编写过程遇到的问题

  8-1:忘记是怎么解决了

 

   8-2:

 

    解决:

 

 

 效果:---此效果也借助了触发器实现的

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

posted @   じ逐梦  阅读(454)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示