WPF入门(二)我的第一个Demo

WPF第一个DEMO

最近学习WPF,由于此前并未接触过C#相关项目。本次学习,分两个部分,该部分使用常规设计方式。即使用非MVVM设计模式。后续会重写一个MVVM模式的代码。

预览效果

本次主要实现对学生的增删改查操作。

页面效果如下:

一、创建项目

本次使用的是Visual Studio 2017 不同的版本界面可能有些不同。

打开Visual Studio 依次点击:文件 ->新建->项目

 

 选择Visual C# ->Windows 桌面 ->WPF应用(.NET Framework)

 

二、创建查询列表

先新建Student类

右击MyFirstWPFDemo->添加-> 类新建Student.cs

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
​
namespace MyFirstWPFDemo
{
​
   public  class Student : INotifyPropertyChanged
    {
​
        public event PropertyChangedEventHandler PropertyChanged;
​
        private int id;
​
        private string name;
​
        private int age;
​
        private Sex sex;
​
        private string hobby;
​
  
        public static Student GetStudent()
        {
            return new Student();
        }
​
​
        private Student()
        {
        }
        public Student(int id, string name, int age, Sex sex, string hobby)
        {
            this.Id = id;
            this.Name = name;
            this.Age = age;
            this.Sex = sex;
            this.Hobby = hobby;
        }
        public int Id
        {
            get => id;
            set
            {
                id = value;
                OnPropertyChanged("Id");
            }
        }
        public string Name
        {
            get => name;
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }
        public int Age
        {
            get => age;
            set
            {
                age = value;
                OnPropertyChanged("Age");
            }
        }
        public Sex Sex
        {
            get => sex;
            set
            {
                sex = value; OnPropertyChanged("Sex");
            }
        }
        public string Hobby
        {
            get => hobby;
            set
            {
                hobby = value; OnPropertyChanged("Hobby");
            }
        }
​
        protected internal virtual void OnPropertyChanged(string propertyName)
        {
            /**
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            **/
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
​
        public override string ToString()
        {
            return "{id=" + Id + "  ,name=" + Name + " ,age= " + Age + " ,sex=" + Sex + " , hobby= " + Hobby + "} ";
        }
​
        public Student Clone()
        {
            Student student = new Student(this.id, this.name, this.age, this.sex, this.hobby);
            return student;
        }
    }
​
}
​

新建Sex.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
​
namespace MyFirstWPFDemo
{
    public enum Sex
    {
        男,
        女
    }
}

新建StudentDB.cs 模拟本地数据存储

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
​
namespace MyFirstWPFDemo
{
    public class StudentDB
    {
        private static ObservableCollection<Student> students = new ObservableCollection<Student>()
        {
           new Student(1,"张三", 23, Sex.男, "乒乓球"),
           new Student(2,"李四", 20, Sex.男, "游泳"),
           new Student(3,"丽丽", 18, Sex.女, "跳舞")
        };
​
        public static ObservableCollection<Student> QueryStudent()
        {
            ObservableCollection<Student> stus = new ObservableCollection<Student>();
            foreach (Student stu in StudentDB.students)
            {
                stus.Add((Student)stu.Clone());
            }
            return stus;
        }
        public static ObservableCollection<Student> QueryStudent(string search)
        {
            ObservableCollection<Student> stus = new ObservableCollection<Student>();
            foreach (Student stu in StudentDB.students)
            {
                if (string.IsNullOrEmpty(search))
                {
                    stus.Add((Student)stu.Clone());
                }
                else
                {
                    if (stu.Name.Contains(search))
                    {
                        stus.Add((Student)stu.Clone());
                    }
                }
            }
            return stus;
        }
​
        public static ObservableCollection<Student> Add(Student student)
        {
            StudentDB.students.Add(student);
            ObservableCollection<Student> stus = new ObservableCollection<Student>();
            foreach (Student stu in StudentDB.students)
            {
                stus.Add((Student)stu.Clone());
            }
            return stus;
        }
        public static ObservableCollection<Student> Delete(Student student)
        {
​
            //移除StudentDB.students值
            for (int i = 0; i < StudentDB.students.Count; i++)
            {
                if (StudentDB.students[i].Id == student.Id)
                {
                    StudentDB.students.Remove(StudentDB.students[i]);
                    break;
                }
​
            }
            ObservableCollection<Student> stus = new ObservableCollection<Student>();
            foreach (Student stu in StudentDB.students)
            {
                stus.Add((Student)stu.Clone());
            }
            return stus;
        }
​
        public static ObservableCollection<Student> Edit(Student student)
        {
            //修改 StudentDB.students值
            for (int i = 0; i < StudentDB.students.Count; i++)
            {
                if (StudentDB.students[i].Id == student.Id)
                {
                    //修改
                    StudentDB.students[i] = student;
                    break;
                }
​
            }
​
            ObservableCollection<Student> stus = new ObservableCollection<Student>();
            foreach (Student stu in StudentDB.students)
            {
                stus.Add((Student)stu.Clone());
            }
            return stus;
        }
​
        public static int GetStudentDBId()
        {
            int tempId = 0;
​
            foreach (Student stu in StudentDB.students)
            {
                if (stu.Id >= tempId)
                {
                    tempId = stu.Id;
                }
            }
            tempId++;
            return tempId;
        }
​
    }
}

添加背景图片,在根目录新建文件夹Resources, 将背景图片background.png 放入该目录。

编辑MainWindow.xaml

<Window x:Class="MyFirstWPFDemo.MainWindow"
        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:MyFirstWPFDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
​
    <Window.Resources>
        <Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}">
            <Setter Property="FontFamily" Value="楷体"/>
            <Setter Property="FontSize"  Value="16"/>
            <Setter Property="Foreground" Value="OrangeRed"/>
            <Setter Property="FontWeight" Value="Light" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.Background>
            <ImageBrush ImageSource="Resources/background.png" />
        </Grid.Background>
        <Grid >
            <!--行-->
            <Grid.RowDefinitions>
                <RowDefinition Height="100"/>
                <RowDefinition Height="50"/>
                <RowDefinition Height="300"/>
                <RowDefinition Height="50"/>
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Center" >
​
            </StackPanel>
            <StackPanel Grid.Row="1" Margin="5">      
            </StackPanel>
            <DataGrid  Grid.Row="2"   Name="listStudent" ItemsSource="{Binding}" AutoGenerateColumns="False"  Height="300">
                <DataGrid.Columns >
                    <DataGridTextColumn Header="Id" Width="100" Binding="{Binding Id  ,Mode=OneWay}"/>
                    <DataGridTextColumn Header="姓名" Width="100" Binding="{Binding Name  ,Mode=OneWay}"/>
                    <DataGridTextColumn  Header="年龄" Width="100" Binding="{Binding Age  ,Mode=OneWay}"/>
                    <DataGridTextColumn  Header="性别" Width="100" Binding="{Binding Sex  ,Mode=OneWay}"/>
                    <DataGridTextColumn  Header="爱好" Width="Auto" MinWidth="150" Binding="{Binding Hobby}"/>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
​
</Window>
​

编辑MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
​
namespace MyFirstWPFDemo
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<Student> students;
​
        public MainWindow()
        {
            InitializeComponent();
            students = StudentDB.QueryStudent();
            this.listStudent.DataContext = students;
        }
       
    }
}
​

效果如图所示:

三、添加查询功能

给MainWindow.xaml 添加查询功能

                <TabPanel  Name="tabPanel">
                    <TextBlock Text="用户姓名:"   
                               Style="{StaticResource TextBlockStyle}"/>
                    <TextBox Name="searchValue" Width="100"  />
                    <Button  Name="SearchButton"  Content="查询" 
                            Click="Search_Click" HorizontalAlignment="Right"/>
                </TabPanel>

完整代码为:

<Window x:Class="MyFirstWPFDemo.MainWindow"
        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:MyFirstWPFDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
​
    <Window.Resources>
        <Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}">
            <Setter Property="FontFamily" Value="楷体"/>
            <Setter Property="FontSize"  Value="16"/>
            <Setter Property="Foreground" Value="OrangeRed"/>
            <Setter Property="FontWeight" Value="Light" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.Background>
            <ImageBrush ImageSource="Resources/background.png" />
        </Grid.Background>
        <Grid >
            <!--行-->
            <Grid.RowDefinitions>
                <RowDefinition Height="100"/>
                <RowDefinition Height="50"/>
                <RowDefinition Height="300"/>
                <RowDefinition Height="50"/>
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" Margin="5" 
                        HorizontalAlignment="Left" VerticalAlignment="Center" >
                <TabPanel  Name="tabPanel">
                    <TextBlock Text="用户姓名:"   
                               Style="{StaticResource TextBlockStyle}"/>
                    <TextBox Name="searchValue" Width="100"  />
                    <Button  Name="SearchButton"  Content="查询" 
                            Click="Search_Click" HorizontalAlignment="Right"/>
                </TabPanel>
            </StackPanel>
            <StackPanel Grid.Row="1" Margin="5">
              
            </StackPanel>
            <DataGrid  Grid.Row="2"   Name="listStudent" ItemsSource="{Binding}" AutoGenerateColumns="False"  Height="300">
                <DataGrid.Columns >
                    <DataGridTextColumn Header="Id" Width="100" Binding="{Binding Id  ,Mode=OneWay}"/>
                    <DataGridTextColumn Header="姓名" Width="100" Binding="{Binding Name  ,Mode=OneWay}"/>
                    <DataGridTextColumn  Header="年龄" Width="100" Binding="{Binding Age  ,Mode=OneWay}"/>
                    <DataGridTextColumn  Header="性别" Width="100" Binding="{Binding Sex  ,Mode=OneWay}"/>
                    <DataGridTextColumn  Header="爱好" Width="Auto" MinWidth="150" Binding="{Binding Hobby}"/>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
​
</Window>
​

添加Search_Click点击事件

        private void Search_Click(object sender, RoutedEventArgs e)
        {
            this.students = StudentDB.QueryStudent(this.searchValue.Text);
​
            this.listStudent.DataContext = students;
        }

效果如图所示:

四、添加列表按钮

列表DataGrid.Columns中添加一下代码

<DataGridTemplateColumn Header="操作">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" >
                <Button  Name="Edit" Content="修改"  Click="Edit_Click"  />
                <Button Name="Delete" Content="删除" Click="Delete_Click" />
                <Button Name="Test" Content="路由事件"  Background="YellowGreen" />
            </StackPanel>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

完整代码为:

<Window x:Class="MyFirstWPFDemo.MainWindow"
    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:MyFirstWPFDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}">
            <Setter Property="FontFamily" Value="楷体"/>
            <Setter Property="FontSize"  Value="16"/>
            <Setter Property="Foreground" Value="OrangeRed"/>
            <Setter Property="FontWeight" Value="Light" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.Background>
            <ImageBrush ImageSource="Resources/background.png" />
        </Grid.Background>
        <Grid >
            <!--行-->
            <Grid.RowDefinitions>
                <RowDefinition Height="100"/>
                <RowDefinition Height="50"/>
                <RowDefinition Height="300"/>
                <RowDefinition Height="50"/>
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Center" >
                <TabPanel  Name="tabPanel">
                    <TextBlock Text="用户姓名:"   Style="{StaticResource TextBlockStyle}"/>
                    <TextBox Name="searchValue" Width="100"  />
                    <Button  Name="SearchButton"  Content="查询" Click="Search_Click" HorizontalAlignment="Right"/>
                </TabPanel>
            </StackPanel>
            <StackPanel Grid.Row="1" Margin="5"></StackPanel>
            <DataGrid  Grid.Row="2"   Name="listStudent" ItemsSource="{Binding}" AutoGenerateColumns="False"  Height="300">
                <DataGrid.Columns >
                    <DataGridTextColumn Header="Id" Width="100" Binding="{Binding Id  ,Mode=OneWay}"/>
                    <DataGridTextColumn Header="姓名" Width="100" Binding="{Binding Name  ,Mode=OneWay}"/>
                    <DataGridTextColumn  Header="年龄" Width="100" Binding="{Binding Age  ,Mode=OneWay}"/>
                    <DataGridTextColumn  Header="性别" Width="100" Binding="{Binding Sex  ,Mode=OneWay}"/>
                    <DataGridTextColumn  Header="爱好" Width="Auto" MinWidth="150" Binding="{Binding Hobby}"/>
                    <DataGridTemplateColumn Header="操作">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal" >
                                    <Button  Name="Edit" Content="修改"  Click="Edit_Click"  />
                                    <Button Name="Delete" Content="删除" Click="Delete_Click" />
                                </StackPanel>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
</Window>

添加后端代码:

private void Edit_Click(object sender, RoutedEventArgs e) {

}

private void Delete_Click(object sender, RoutedEventArgs e) {

	this.students = StudentDB.Delete((Student) this.listStudent.SelectedItem);
	this.students = StudentDB.QueryStudent(this.searchValue.Text);
	this.listStudent.DataContext = students;
}

现在已经完成修改,删除按钮添加。此时仅删除按钮有效果,修改按钮暂时还没有效果。

效果,如图所示:

五、实现修改功能

新建一个StudentEditWindow.xaml 窗口。

右键MyFirstWPFDemo -> 添加 -> 窗口

编辑页前端代码如下:

<Window x:Class="MyFirstWPFDemo.StudentEditWindow"
    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:MyFirstWPFDemo"
        mc:Ignorable="d"
        Title="StudentEditWindow" Height="380" Width="600">
    <Window.Resources>
        <local:SexToBoolConverter x:Key="SexToBoolConverter"></local:SexToBoolConverter>
    </Window.Resources>
    <Grid>
        <Grid.Background>
            <ImageBrush ImageSource="Resources/background.png" />
        </Grid.Background>
        <Grid  HorizontalAlignment="Center" VerticalAlignment="Center">
            <Grid.RowDefinitions>
                <RowDefinition Height="50"/>
                <RowDefinition Height="100"/>
                <RowDefinition Height="100"/>
                <RowDefinition Height="Auto"  MinHeight="90"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150" />
                <ColumnDefinition Width="50" />
                <ColumnDefinition Width="Auto" MinWidth="150"/>
            </Grid.ColumnDefinitions>
            <TabPanel Grid.Row="1"  HorizontalAlignment="Center" VerticalAlignment="Center">
                <TextBlock  Text="姓名:" HorizontalAlignment="Left" />
                <TextBlock  Text="{Binding Name}" Width="80"  HorizontalAlignment="Left" />
            </TabPanel>
            <TabPanel Grid.Row="1"  Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center" >
                <TabPanel>
                    <TextBlock Text="年龄:"/>
                    <TextBox Text="{Binding Age}" Width="100"/>
                </TabPanel>
            </TabPanel>
            <TabPanel Grid.Row="2" Grid.ColumnSpan="1" HorizontalAlignment="Center" VerticalAlignment="Center" >
                <TabPanel>
                    <TextBlock Text="爱好:"/>
                    <TextBox Text="{Binding Hobby}" Width="Auto" MinWidth="50"/>
                </TabPanel>
            </TabPanel>
            <StackPanel Grid.Row="2" Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center" >
                <TabPanel>
                    <RadioButton GroupName="Sex" IsChecked="{Binding Sex,Converter={StaticResource SexToBoolConverter},ConverterParameter=0}">男</RadioButton>
                    <RadioButton GroupName="Sex" IsChecked="{Binding Sex,Converter={StaticResource SexToBoolConverter},ConverterParameter=1}">女</RadioButton>
                </TabPanel>
            </StackPanel>
            <TabPanel Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center"  Grid.Column="2"   >
                <Button  Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="1" Content="确定" Click="Submit_Click" />
                <TextBlock Width="20"/>
                <Button  Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="1" Content="取消" Click="Cancel_Click"/>
            </TabPanel>
        </Grid>
    </Grid>
</Window>

编辑页后端代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace StudentDemo2
{
    /// <summary>
    /// StudentEditWindow.xaml 的交互逻辑
    /// </summary>
    public partial class StudentEditWindow : Window
    {
        private object selected;
        public StudentEditWindow()
        {
            InitializeComponent();
        }
        public StudentEditWindow(object selectedItem) : this()
        {

            this.selected = selectedItem;
            this.DataContext = ((Student)selectedItem).Clone();

        }
        private void Submit_Click(object sender, RoutedEventArgs e)
        {
            Student stu =(Student)this.selected ;
            stu.Hobby = ((Student)this.DataContext).Hobby;
            stu.Sex = ((Student)this.DataContext).Sex;
            stu.Age = ((Student)this.DataContext).Age;
            this.Close();
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

    }
}

添加转换器 SexToBoolConverter.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace MyFirstWPFDemo
{
    class SexToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Sex s = (Sex)value;
            return s == (Sex)int.Parse(parameter.ToString());
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool isChecked = (bool)value;
            if (!isChecked)
            {
                return null;
            }
            return (Sex)int.Parse(parameter.ToString());
        }
    }
}

完善MainWindow.xaml.cs 中的Edit_Click方法

private void Edit_Click(object sender, RoutedEventArgs e) {
    
	Student stu = (Student) this.listStudent.SelectedItem;

	StudentEditWindow studentEdit = new StudentEditWindow(stu);

	studentEdit.ShowDialog();

	this.students = StudentDB.Edit(stu);

	this.students = StudentDB.QueryStudent(this.searchValue.Text);

	this.listStudent.DataContext = students;

}

此时,列表中的修改按钮生效,效果如图所示

六、实现新增功能

在 主窗口MainWindow.xaml 添加新增按钮

<StackPanel Grid.Row="1" Margin="5">
	<Button Name="Add" Content="新增" Click="Add_Click" HorizontalAlignment="Left"/>
</StackPanel>

后端MainWindow.xaml.cs 新增方法Add_Click

private void Add_Click(object sender, RoutedEventArgs e) {

	StudentAddWindow studentAdd = new StudentAddWindow();
	studentAdd.ShowDialog();
	Student stu = (Student) studentAdd.GetTempStudent();

	if (stu != null) {
		stu.Id = StudentDB.GetStudentDBId();
		this.students = StudentDB.Add(stu);
		this.listStudent.DataContext = students;
	}

}

新增 StudentAddWindow.xaml 窗体。

前端代码为:

<Window x:Class="MyFirstWPFDemo.StudentAddWindow" 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:MyFirstWPFDemo" mc:Ignorable="d" Title="StudentAddWindow"
Height="380" Width="600">
	<Window.Resources>
		<local:SexToBoolConverter x:Key="SexToBoolConverter">
		</local:SexToBoolConverter>
	</Window.Resources>
	<Grid>
		<Grid.Background>
			<ImageBrush ImageSource="Resources/background.png" />
		</Grid.Background>
		<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
			<Grid.RowDefinitions>
				<RowDefinition Height="50" />
				<RowDefinition Height="100" />
				<RowDefinition Height="100" />
				<RowDefinition Height="Auto" MinHeight="90" />
			</Grid.RowDefinitions>
			<Grid.ColumnDefinitions>
				<ColumnDefinition Width="150" />
				<ColumnDefinition Width="50" />
				<ColumnDefinition Width="Auto" MinWidth="150" />
			</Grid.ColumnDefinitions>
			<TabPanel Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
				<TextBlock Text="姓名:" HorizontalAlignment="Left" />
				<TextBox Text="{Binding Name}" Width="80" HorizontalAlignment="Left" />
			</TabPanel>
			<TabPanel Grid.Row="1" Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center">
				<TabPanel>
					<TextBlock Text="年龄:" />
					<TextBox Text="{Binding Age}" Width="100" />
				</TabPanel>
			</TabPanel>
			<TabPanel Grid.Row="2" Grid.ColumnSpan="1" HorizontalAlignment="Center"
			VerticalAlignment="Center">
				<TabPanel>
					<TextBlock Text="爱好:" />
					<TextBox Text="{Binding Hobby}" Width="Auto" MinWidth="50" />
				</TabPanel>
			</TabPanel>
			<StackPanel Grid.Row="2" Grid.Column="3" HorizontalAlignment="Center"
			VerticalAlignment="Center">
				<TabPanel>
					<RadioButton GroupName="Sex" IsChecked="{Binding Sex,Converter={StaticResource SexToBoolConverter},ConverterParameter=0}">
						男
					</RadioButton>
					<RadioButton GroupName="Sex" IsChecked="{Binding Sex,Converter={StaticResource SexToBoolConverter},ConverterParameter=1}">
						女
					</RadioButton>
				</TabPanel>
			</StackPanel>
			<TabPanel Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center"
			Grid.Column="2">
				<Button Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="1" Content="确定"
				Click="Submit_Click" />
				<TextBlock Width="20" />
				<Button Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="1" Content="取消"
				Click="Cancel_Click" />
			</TabPanel>
		</Grid>
	</Grid>
</Window>

后端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace MyFirstWPFDemo {
	/// <summary>
	/// StudentAddWindow.xaml 的交互逻辑
	/// </summary>
	public partial class StudentAddWindow: Window {

		private Student student;

		public StudentAddWindow() {
			InitializeComponent();

			this.DataContext = Student.GetStudent();
		}

		private void Submit_Click(object sender, RoutedEventArgs e) {
			this.student = (Student) this.DataContext;
			this.Close();
		}

		private void Cancel_Click(object sender, RoutedEventArgs e) {
			this.Close();
		}

		public Student GetTempStudent() {
			return this.student;
		}
	}
}

效果如图所示:

七、实现查询框清除功能

该处使用命令方式清除查询框,该处代码相对较难。可以与普通点击事件查询按钮对比。

MainWindow.xaml中,在查询按钮旁边添加清除按钮

<Button  Name="ClearButton"  Content="命令方式清除"  HorizontalAlignment="Right"/>

添加后端代码:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MyFirstWPFDemo {
	/// <summary>
	/// MainWindow.xaml 的交互逻辑
	/// </summary>
	public partial class MainWindow: Window {
		private ObservableCollection < Student > students;

		//申明并定义命令
		private RoutedCommand clearCmd = new RoutedCommand("Clear", typeof(MainWindow));

		public MainWindow() {
			InitializeComponent();
			//命令初始化
			InitialiizeCommand();
			students = StudentDB.QueryStudent();
			this.listStudent.DataContext = students;
		}

		//初始化命令
		private void InitialiizeCommand() {
			//把命令赋值给命令源(发送者)并指定快捷方键
			this.ClearButton.Command = this.clearCmd;
			this.clearCmd.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Alt));

			//指定命令目标
			this.ClearButton.CommandTarget = this.searchValue;

			//创建命令联
			CommandBinding cb = new CommandBinding();
			cb.Command = this.clearCmd; //只关注与clearCmd相关事件
			cb.CanExecute += new CanExecuteRoutedEventHandler(Cb_CanExecute);
			cb.Executed += new ExecutedRoutedEventHandler(Cb_Executed);

			//把命令关联安置到外围控件上
			this.tabPanel.CommandBindings.Add(cb);

		}

		//当探测命令是否可以执行是,此方法被调用
		void Cb_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
			if (string.IsNullOrEmpty(this.searchValue.Text)) {
				e.CanExecute = false;
			} else {
				e.CanExecute = true;
			}
			//避免继续向上传而降低程序性能
			e.Handled = true;

		}

		void Cb_Executed(object sender, ExecutedRoutedEventArgs e) {
			this.searchValue.Clear();
            this.listStudent.DataContext = 
                 StudentDB.QueryStudent(this.searchValue.Text);   
			//避免继续向上传而降低程序性能
			e.Handled = true;
		}

		private void Search_Click(object sender, RoutedEventArgs e) {

			this.students = StudentDB.QueryStudent(this.searchValue.Text);

			this.listStudent.DataContext = students;

		}
		private void Add_Click(object sender, RoutedEventArgs e) {

			StudentAddWindow studentAdd = new StudentAddWindow();

			studentAdd.ShowDialog();

			Student stu = (Student) studentAdd.GetTempStudent();

			if (stu != null) {
				stu.Id = StudentDB.GetStudentDBId();
				this.students = StudentDB.Add(stu);
				this.listStudent.DataContext = students;
			}

		}

		private void Edit_Click(object sender, RoutedEventArgs e) {
			Student stu = (Student) this.listStudent.SelectedItem;

			StudentEditWindow studentEdit = new StudentEditWindow(stu);

			studentEdit.ShowDialog();

			this.students = StudentDB.Edit(stu);

			this.students = StudentDB.QueryStudent(this.searchValue.Text);

			this.listStudent.DataContext = students;

		}

		private void Delete_Click(object sender, RoutedEventArgs e) {

			this.students = StudentDB.Delete((Student) this.listStudent.SelectedItem);

			this.students = StudentDB.QueryStudent(this.searchValue.Text);

			this.listStudent.DataContext = students;

		}

	}
}

效果如图所示:

八、实现列表路由事件按钮

MainWindow.xaml主窗体列表中,在删除按钮位置,新增路由按钮。

同时在DataGrid上添加路由点击事件RouteClicked事件。

代码如下

<DataGrid Grid.Row="2" Name="listStudent" ItemsSource="{Binding}" AutoGenerateColumns="False"
Height="300" ButtonBase.Click="RouteClicked">
	<DataGrid.Columns>
		<DataGridTextColumn Header="Id" Width="100" Binding="{Binding Id  ,Mode=OneWay}"
		/>
		<DataGridTextColumn Header="姓名" Width="100" Binding="{Binding Name  ,Mode=OneWay}"
		/>
		<DataGridTextColumn Header="年龄" Width="100" Binding="{Binding Age  ,Mode=OneWay}"
		/>
		<DataGridTextColumn Header="性别" Width="100" Binding="{Binding Sex  ,Mode=OneWay}"
		/>
		<DataGridTextColumn Header="爱好" Width="Auto" MinWidth="150" Binding="{Binding Hobby}"
		/>
		<DataGridTemplateColumn Header="操作">
			<DataGridTemplateColumn.CellTemplate>
				<DataTemplate>
					<StackPanel Orientation="Horizontal">
						<Button Name="Edit" Content="修改" Click="Edit_Click" />
						<Button Name="Delete" Content="删除" Click="Delete_Click" />
						<Button Name="Route" Content="路由事件" Background="YellowGreen" />
					</StackPanel>
				</DataTemplate>
			</DataGridTemplateColumn.CellTemplate>
		</DataGridTemplateColumn>
	</DataGrid.Columns>
</DataGrid>

MainWindow.xaml.cs中添加RouteClicked方法。

private void RouteClicked(object sender, RoutedEventArgs e) {

	if ("Route".Equals((e.OriginalSource as FrameworkElement).Name)) {
		Student stu = (Student) this.listStudent.SelectedItem;
		MessageBox.Show("这是一个路由事件:" + stu.ToString());
	}

}

效果如下:

九、添加第三方控件库

以上页面已近实现了对学生数据的增删改查操作。但是页面看起来不是特别美观。

下面将引入第三方控件库(HandyControl)来优化我们的代码。

HandyControl:GitHub - HandyOrg/HandyControl: Contains some simple and commonly used WPF controls

欢迎使用HandyControl | HandyOrg

开始使用:

在Visual Studio上 工具栏上选择

工具 -> NuGet 包管理器 ->管理解决方案的NuGet程序包。

在浏览选项搜索HandyControl并下载安装。

在App.xaml中添加以下代码:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>
            <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

添加命名空间:

xmlns:hc="https://handyorg.github.io/handycontrol"

至此配置完成。效果如下图:

源代码如下:

WPFStudentDemo-C#文档类资源-CSDN下载

  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值