使用 WPF 和 MySQL 搭建小型人资管理系统——主要页面

大家过年好!祝大家新年快乐~~~ 在新的一年身体健康,心想事成~~~

开始第三篇!

这一篇的主要内容会说一下剩下的几个页面,它们之间的逻辑关系,以及每个页面中比较难实现的部分。


#页面说明
在第二篇中,我们介绍了登录界面和主页面的布局及难点,今天我们主要介绍人事管理页、用户管理页、员工详情页、添加信息页以及修改信息页。
先放图给大家看一看~~~
人事管理页.png

人事管理页,点击菜单栏的第一项即可转到此页面。可以在此查看所有员工的主要信息,并可以多条件查询筛选员工。点击最后一列的详情图标,即可转到员工详情页查看所选员工的详细信息。可以选中一个或按住 Ctrl 选中多个员工执行删除操作。点击添加按钮就会转到添加信息页。
员工详情页.png

员工详情页,是人事管理页的子页面。根据客户给出的信息项进行整合归类,展示员工的详细信息。其中每一项信息都处于不可编辑状态,点击打印按钮会弹出打印界面,点击修改会弹出修改界面。
修改信息页.png

修改信息页,是员工详情页的子页面。展示的信息和员工详情页大致一样,其中每项都可以被编辑修改。点击取消修改则关闭此窗口且不进行其他操作,点击保存修改则关闭此窗口且更新员工详情页的信息。
添加信息页.png

添加信息页,是人事管理页的子页面。点击人事管理页的添加按钮即可转到此页面。与修改信息页类似,其中的每项都可被填写和编辑。它主要用来从零开始填写某个员工的信息,而修改信息页主要用于在已经填好的基础上进行少数地方的修改。
用户管理页.png

用户管理页,点击菜单栏的第二项即可转到此页面。它的主要作用有两个,一是管理登录用户的权限,可以添加新的用户并指定其权限(权限若为人资,则具有最高权限。可以执行所有操作,查看所有页面;权限若为高管,则只能查看人事管理页、员工详情页和帮助页面),也可选中一个或多个用户进行删除。第二个作用是可以查看近一个月的所有登录此客户端的用户名和登录时间。


展示的页面就是这么多了,可能有的小伙伴会发现还有一个挺重要的页面没有展示,也就是菜单栏的第三项——数据备份。事实上,这个页面并没有完成… … 我们刚开始做到这里的时候很头大,不知道怎么进行,查阅资料后发现需要和服务器相配合才能继续,而且还涉及到一些问题,比如想要从若干备份中选择一个恢复到那时候的状态,如何才能在客户端点击恢复按钮后把命令发送给服务器,之类的问题,当时我们并没有这么多精力来解决这个问题,于是就采取了简化的策略,先不实现这个页面和功能,而是给服务器上的数据库设置一个定期备份的脚本,如果真的要恢复某个备份,就通过直接操作服务器的数据库来实现… …

… …

(于是到了现在也没实现)

经验:如果要完成的项目中有个功能目前较难实现,在资源和精力有限的情况下可以考虑先进行简化处理,优先完成项目主体功能,完成这些以后,或者是在项目的下个版本中,在集中精力处理这些问题。

虽然听起来很简单,但是有时候我们就容易陷入一种死磕的状态,不搞出来这个就很不甘心很难受,于是就耽误了其他更重要的任务。保持大局观,一定不能让我们的思维被情绪主导,而是要让情绪跟随思维。


页面的逻辑结构

我们已经知道了几个页面的样子和它们之间的跳转关系,那么在程序中它们是一个怎么样的结构呢?

首先,在 VS 项目自带的 App.xaml 中,可以看到如下代码:

<Application x:Class="DatabaseProject.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:DatabaseProject"
             StartupUri="MainWindow.xaml"
             ShutdownMode="OnExplicitShutdown">
</Application>

其中 StartupUri 表示运行项目工程时首先从 MainWindow.xaml 开始启动,ShutdownMode 用来判断判断调用 ShutDown 方法终止程序的条件,如下表:

ShutdownMode 的值说明
OnLastWindowClose (默认值)最后一个窗体关闭或调用Application对象的Shutdown() 方法时,应用程序关闭。
OnMainWindowClose启动窗体关闭或调用Application对象的Shutdown()方法时,应用程序关闭。
OnExplicitShutdown只有在调用Application对象的Shutdown()方法时,应用程序才会关闭。

我们刚开始没有设置这个值,结果在运行的时候点击右上角红叉无法完全退出,虽然关掉了页面,但是进程仍然在运行。后来打包生成应用程序时也是这样,必须在任务管理器中停止进程才行。经过多方查找资料,最后的解决方法是,把 ShutdownMode 的值设置成了 OnExplicitShutdown,并且在主程序窗口所在页面的 cs 文件中类的最后加上了下面的代码:

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            Application.Current.Shutdown();
        }

这样相当于点右上角红叉时强制关闭了进程并回收了资源,是比较暴力的做法,这对于一些需要在退出前保存当前状态的程序来说是不适用的。

接着刚才的说,首先 StartupUri 指定了从 MainWindow.xaml 开始启动,其实就是先启动登录窗口。接下来用户登录,如果身份核实无误,就先用this.Hide() 隐藏当前窗口,然后创建一个 MainWindow1 类型的变量(就是主程序窗口的类型)并对其调用Show()方法。

在 MainWindow1.xaml.cs 中,添加四个 static 的 Page 变量,对应着菜单栏上的四个选项,跳转页面的代码已经在系列的第二篇的最后给出。之所以要设置成 static,是因为这四个页面都是唯一的,而且这样可以方便后续在各种情况下对它们的调用。

    public partial class MainWindow1 : Window
    {
        public static Page1 p1;//人事管理页
        public static Page2 p2;//用户管理页
        public static Page3 p3;
        public static Page4 p4;
        //省略下面的代码
        ...
    }

同理,在 Page1.xaml.cs 中添加两个 static 的 Page 变量,也是因为员工详情页和添加信息页都是唯一的。不同的员工的详情页不同,是因为改变了这个唯一的详情页里的某些变量。它就像一个收纳盒,结构已经搭建好了,当查看张三的信息时,把里面都放上张三的东西;当查看李四的信息时,先清空里面的东西,然后再放上李四的东西。(其实也可以不设置成 static,相当于给每个人一个收纳盒,但我觉得在查看很多员工信息的时候可能会占用较多内存空间,因此在退出该页面时需要清理资源)

    public partial class MainWindow1 : Window
    {
        public static Detail_info_Page detailInfoPage;//员工详情页
        public static Add_info_Page addinfopage;//添加信息页
        //省略下面的代码
        ...
    }

对于修改信息页,为了方便我就没设置成 static,也是可以运行的 : )

    private void Revise_Button_Click(object sender, RoutedEventArgs e)
    {
        Revise_Window rw1 = new Revise_Window();
        rw1.ShowDialog();
    }

就说这么多了,接下来我们看看每个页面中遇到的问题。


#遇到的问题

  • 人事管理页的高级查询部分,怎么实现点击后呈现隐藏部分的?

高级查询的点击与隐藏.png

WPF 有个控件叫 Expander,可以用于实现这个功能。在其中先添加一个 Grid,再在 Grid 中放入其他控件。在 xaml 结合其他的控件用法如下:

<Expander Header="高级查询" FlowDirection="RightToLeft">
    <Grid>
        <WrapPanel>
            <RadioButton Name="radio1" Content="男 "/>
            <RadioButton Name="radio2" Content="女 " />
        </WrapPanel>
        <ComboBox SelectionChanged="ComboBox_SelectionChanged"
                  SelectedIndex="0">
            <ComboBoxItem HorizontalContentAlignment="Center">不限</ComboBoxItem>
            <ComboBoxItem HorizontalContentAlignment="Center">财务</ComboBoxItem>
        </ComboBox>
        <Button BorderThickness="0"
                Background="#85B6FF"
                Foreground="White"
                Content="查询"
                Click="AdvanceSearch_Button_Click"></Button>
    </Grid>
</Expander>
  • 人事管理页中表格的样式是怎么实现的?

这里的样式我有部分借鉴了网上的例子。除了本身的蓝白色交替以外,还有鼠标悬浮和选中的效果,如下图:(浅黄是鼠标悬浮效果,深黄是选中效果)

hover效果、selected效果与普通效果.png

接下来的代码复制粘贴就可以了 : )

<!--xaml代码-->
<Page.Resources>
        <!-- DataGridColumnHeader style -->
        <Style x:Key="ColumnHeaderStyle1"
               TargetType="DataGridColumnHeader">
            <Setter Property="FontSize"
                    Value="20" />
            <Setter Property="Background"
                    Value="White" />
            <Setter Property="Foreground"
                    Value="#555555" />
            <Setter Property="Height"
                    Value="50" />
            <Setter Property="BorderThickness"
                    Value="1" />
            <Setter Property="BorderBrush">
                <Setter.Value>
                    <SolidColorBrush Color="#BBBBBB"
                                     Opacity="1"></SolidColorBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="HorizontalContentAlignment"
                    Value="Center" />
        </Style>
        <!-- DataGridRow style -->
        <Style x:Key="DataGridRowStyle1"
               TargetType="DataGridRow">
            <Setter Property="Background"
                    Value="Black" />
            <Setter Property="Height"
                    Value="50" />
            <Setter Property="FontSize"
                    Value="20" />
            <Setter Property="Foreground"
                    Value="#3E3E3E" />
            <Setter Property="HorizontalContentAlignment"
                    Value="Center" />
            <Style.Triggers>
                <!--隔行换色-->
                <Trigger Property="AlternationIndex"
                         Value="0">
                    <Setter Property="Background"
                            Value="#F3F8FF" />
                </Trigger>
                <Trigger Property="AlternationIndex"
                         Value="1">
                    <Setter Property="Background"
                            Value="White" />
                </Trigger>
                <Trigger Property="IsMouseOver"
                         Value="True">
                    <Setter Property="Background"
                            Value="#FFF5C2" />
                </Trigger>
                <Trigger Property="IsSelected"
                         Value="True">
                    <Setter Property="Background"
                            Value="#FFED94" />
                    <Setter Property="Foreground"
                            Value="Black" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <!-- DataGridCell style -->
        <Style x:Key="DataGridCellStyle"
               TargetType="DataGridCell">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="DataGridCell">
                        <TextBlock TextAlignment="Center"
                                   VerticalAlignment="Center"> 
                        <ContentPresenter /></TextBlock>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsSelected"
                         Value="True">
                    <Setter Property="Foreground"
                            Value="Black" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Page.Resources>


            <DataGrid BorderThickness="0"
                      Name="datagrid1"
                      Height="600"
                      Canvas.Left="71"
                      Canvas.Top="180"
                      Width="1529"
                      Background="#F9F9F9"
                      CanUserSortColumns="False"
                      AutoGenerateColumns="False"
                      CanUserReorderColumns="False"
                      CanUserAddRows="False"
                      AlternationCount="2"
                      DataGrid.ColumnHeaderStyle="{DynamicResource ColumnHeaderStyle1}"
                      DataGrid.RowStyle="{DynamicResource DataGridRowStyle1}"
                      DataGrid.CellStyle="{DynamicResource DataGridCellStyle}"
                      BorderBrush="#9DC4FF"
                      HorizontalGridLinesBrush="#9DC4FF"
                      VerticalGridLinesBrush="#9DC4FF"
                      HeadersVisibility="Column">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="编号"
                                        Binding="{Binding PID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Width="3*"></DataGridTextColumn>
                    <DataGridTextColumn Header="姓名"
                                        Binding="{Binding PName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Width="3*"></DataGridTextColumn>
                    <DataGridTextColumn Header="性别"
                                        Binding="{Binding Sex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Width="2*"></DataGridTextColumn>
                    <DataGridTextColumn Header="年龄"
                                        Binding="{Binding age, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Width="2*"></DataGridTextColumn>
                    <DataGridTextColumn Header="学历"
                                        Binding="{Binding Education, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Width="2*"></DataGridTextColumn>
                    <DataGridTextColumn Header="部门"
                                        Binding="{Binding ODepart, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Width="3*"></DataGridTextColumn>
                    <DataGridTextColumn Header="职称"
                                        Binding="{Binding CPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Width="3*"></DataGridTextColumn>
                    <DataGridTextColumn Header="入司年限"
                                        Binding="{Binding intime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Width="3*"></DataGridTextColumn>
                    <DataGridTemplateColumn>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Image Name="staff_detail_info"
                                       MouseLeftButtonDown="Staff_detail_info_MouseLeftButtonDown"
                                       Height="32"
                                       Width="100"
                                       Source="pack://application:,,,/pic/detail_info.png"
                                       Canvas.Left="1799"
                                       Canvas.Top="540" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
  • 如何实现在表格(datagrid)中插入表示详情的图片,并实现点击跳转?

看到上面的代码的最后的 image 标签,就是插入图片的方式。跳转的方式是用了 MouseLeftButtonDown 属性来实现的。在 xmal 对应的 cs 文件里,加上下面的方法:

        private void Staff_detail_info_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DataRowView row = (DataRowView)((Image)e.Source).DataContext;
            string staff_pid = row["PID"].ToString();
            detailInfoPage = new Detail_info_Page(staff_pid, detail_info_para);
            detailInfoPage.detail_info_page_title.Content = row["PName"].ToString() + "员工详细信息";

            this.NavigationService.Navigate(detailInfoPage);
        }

第一行的写法查了好久才查到,我是打死都写不出来的… …它的作用就是获取到你点击的那一行。第二行获取到所选择的行的员工对应的唯一识别码(PID),第三行对之前声明的静态的员工详情页进行初始化,注意构造函数的第二个参数是用于标识用户是人资还是高管的,detail_info_para 的值在之前就已经确定。实际上在执行完这一句以后,员工详情页的构造函数已经将其生成好了。第四行的作用是将员工的名字加入到员工详情页的标题中。

  • 如何实现添加或删除员工信息后刷新人事管理页中的表格?

添加员工信息后,会通过this.NavigationService.Navigate(MainWindow1.p1)跳转到人事管理页,此时 datagrid 会从数据库提取信息并显示,从而实现更新;而删除员工信息后则手动从数据库提取信息并显示。数据库的操作会放到之后专门说明。

  • 员工详情页的标签栏和表格样式是怎么做的?

员工详情页的标签栏和表格样式.png
可以通过 TabControl 来实现。其中可以包含多个 TabItem,每个 TabItem 中又可以包含其他的控件元素。直接上代码:

            <TabControl BorderThickness="0">
                <TabItem Header=" 基本状况 ">
                    <ScrollViewer>
                        <Grid>
                        <!--可以放置其他控件,只需要让Grid的高度大于ScrollViewer即可看到上下滚动条-->
                        </Grid>
                    </ScrollViewer>
                </TabItem>
                <TabItem Header=" 岗位状况 "/>
                <TabItem Header=" 个人能力模型评估 "/>
                <TabItem Header=" 个人展现类型评估 "/>
                <TabItem Header=" 现任岗位实操 "/>
                <TabItem Header=" 综合评估/人才归类/人资评语 "/>
            </TabControl>

其中 TabItem 的呈现方式也有很多,网上可以找到各种各样的样式。
而表格样式其实就是把两个只有一行的 datagrid 一上一下放置,设置好高度就可以了。这里还需要说一下,客户的要求是有些信息的行数是不固定的,比如曾经担任的职位,还有工作职能标准等等,它们可能只有一行,也可能有十几行。然而 datagrid 的高度是固定的,确定高度后展示的信息的行数就固定了。这里我选择了个简单粗暴的方法,就是把高度设置得多一些,这样在绝大多数情况下都能够显示所有的行了… …

  • 在添加员工信息时,第四个标签栏中需要用到单选框(RadioButton),但是 WPF 自带的单选框太小了,放上去不美观,怎么变大?

最终在 Stackoverflow 上找到了解决方法。使用 Viewbox,可以放大某个控件。代码如下:

                        <Viewbox  Height="30">
                            <StackPanel Orientation="Horizontal"
                                        Width="617">
                                <RadioButton Name="item1"
                                             Width="154" />
                                <RadioButton Name="item2"
                                             Width="154" />
                                <RadioButton Name="item3"
                                             Width="154" />
                                <RadioButton Name="item4"
                                             Width="90" />
                            </StackPanel>
                        </Viewbox>

设置好 RadioButton 的 Width,与表头对其即可。还有就是,WPF 中除了 RadioButton,还有 Calendar 等选择日期控件也比较小,因此也可以用 Viewbox 放大。最终呈现的效果如下图所示。

放大的 RadioButton.png

  • 在查看员工详细信息时,如何达到下图的效果,在之前选择的类型上标上对勾?如果在对应的项下面填上“选中”的话不好看。

用对勾表示选中.png

这里我开始准备放个对勾的图片上去,后来觉得把问题弄复杂了,就想着对勾是否可以作为文本来显示。百度了一下,果然可以打出来 √ √ √ 你可以在中文输入法下输入“对勾”的拼音,应该也会出来这个符号的 : ) 最后把颜色改成红色就 ok 了。

  • 怎么修改 datagrid 使其中的信息不能被修改?

Datagrid 有很多属性可以设置,在 datagrid 标签中设置IsEnabled="False"即可达到这个要求。其他的属性还有 CanUserSortColumns,AutoGenerateColumns,CanUserReorderColumns,CanUserAddRows 等等。从字面意思上也可以知道它们的作用。如果大家想知道它们会造成什么样的不同,可以自行百度,这里就不多说啦。

  • 怎么实现打印的功能?

这个也是个不小的坑,我放在下一篇专门说 : ) 先放一张打印窗口的截图如下:

打印窗口.png
好了,这篇就到这里了~ 打这么多字还真有点累,但也要继续坚持~

再次祝大家新年快乐,在新的一年成为更好的自己!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
管理系统,作为一种高效的企业运营管理工具,旨在通过集成化、系统化的手段,对组织内部的各类资源进行规划、协调、控制和优化,以实现企业战略目标,提升运营效率,增强核心竞争力。以下是对管理系统的详细介绍: 一、定义与构成 管理系统是指由硬件设备、软件应用、数据资源、人员以及相关管理制度共同构建的,用于处理、监控、分析和决策各类业务活动的综合信息系统。它通常包括以下几个核心组成部分: 数据采集模块:负责从各类业务环节中实时、准确地收集信息,形成企业的基础数据资源。 数据分析模块:运用统计学、人工智能等技术对数据进行深度挖掘和智能分析,提供决策支持。 业务流程管理模块:设计、执行、监控和优化业务流程,确保各项任务按照预定规则高效运转。 决策支持模块:基于数据分析结果,为管理者提供直观的可视化报告,辅助其进行科学决策。 用户界面与交互模块:提供友好的人机交互界面,方便用户操作使用。 二、主要类型与功能 管理系统根据所针对的管理对象和领域,可分为多种类型,如: 人力资源管理系统(HRM):涵盖招聘、培训、绩效考核、薪酬福利等人力资源全流程管理,提升人才效能。 客户关系管理系统(CRM):集中管理客户信息,优化销售、营销和服务流程,提升客户满意度和忠诚度。 供应链管理系统(SCM):整合供应商、制造商、分销商、零售商等供应链各环节,实现物流、资金流、信息流的协同运作。 企业资源计划系统(ERP):对企业内部财务、生产、采购、库存、销售等各项资源进行全面集成管理,提高整体运营效率。 项目管理系统(PM):对项目全生命周期进行规划、跟踪、控制,确保项目按时、按质、按预算完成。 三、价值与优势 提高效率:自动化工作流程、标准化业务操作,显著减少人工干预,提升工作效率。 优化决策:实时数据分析与预测,提供精准的决策依据,助力管理层做出明智选择。 资源整合:打破部门壁垒,实现信息共享,优化资源配置,降低运营成本。 合规风控:内置法规遵循机制,强化内部控制,降低经营风险。 持续改进:通过对系统数据的持续监控与分析,驱动业务流程持续优化,促进企业创新与发展。 总的来说,管理系统作为现代企业管理的重要工具,以其强大的数据处理能力、智能化的决策支持和高效的业务流程管理,有力推动了企业的数字化转型,助力企业在日益激烈的市场竞争中保持竞争优势。
WPF(Windows Presentation Foundation)是一种用于创建Windows应用程序的界面开发技术,其基于.NET Framework平台,并使用C#编程语言进行开发。WPF提供了一套强大的工具和框架,使开发人员能够轻松创建富有吸引力、功能丰富的用户界面。 WPF与传统的Windows Forms相比具有许多优势。首先,WPF支持更加灵活和现代化的用户界面设计,可以轻松地创建透明、动画和多媒体效果等视觉效果。其次,WPF具有更好的分离性,允许开发人员将界面逻辑与业务逻辑进行分离,使代码更加清晰和易于维护。此外,WPF还支持数据绑定和样式模板等功能,使界面开发更加高效和可重用。 在使用WPF进行编程时,首先需要了解XAML(Extensible Application Markup Language)语言,它用于定义WPF界面元素和布局。然后,使用C#语言编写代码逻辑,处理用户交互、数据绑定、事件处理等方面的功能。在WPF中,可以通过使用命令模式和MVVM(Model-View-ViewModel)架构来组织和管理代码,以实现更好的代码分离性。 另外,WPF提供了丰富的控件库,开发人员可以使用这些控件来构建各种功能和复杂的界面。同时,WPF还支持自定义控件的开发,开发人员可以根据具体需求创建自己的控件。 总之,WPF是一种强大的界面开发技术,可以帮助开发人员创建出具有丰富功能和吸引力的Windows应用程序。同时,使用C#语言进行开发可以使开发过程更加高效和灵活。无论是初学者还是有经验的开发人员,都可以从WPF编程宝典中学习到丰富的知识和技巧,提高自己的WPF编程能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值