一、代码分析
1.Animal.cs
1.1 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AnimalNamespace
{
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public Animal (string name,int age)
{
Name = name;
Age = age;
}
public virtual string 吃饭()
{
return "我要吃饭";
}
public virtual string Makesound()
{
return "animal sound";
}
public override string ToString()
{
return $"{Name} (Age:{Age})";
}
}
}
1.2 代码分析
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
解释:这些 using 指令用于引入命名空间,允许你使用这些命名空间中定义的类和方法。System 包含基本的系统功能,Collections.Generic 提供泛型集合类,Linq 用于查询操作,Text 提供处理文本的类,Threading.Tasks 提供并行编程类。
namespace AnimalNamespace
{
解释:定义一个命名空间 AnimalNamespace,用于组织代码并避免命名冲突。在这个命名空间内定义的所有类和方法都属于这个命名空间。
public class Animal
{
解释:定义一个公共类 Animal。public 关键字表示这个类可以被其他命名空间中的代码访问。
public string Name { get; set; }
解释:定义一个公共属性 Name。string 是数据类型,表示这个属性存储字符串。{ get; set; } 是属性访问器,表示这个属性可以被读取和写入。
public int Age { get; set; }
解释:定义一个公共属性 Age。int 是数据类型,表示这个属性存储整数。{ get; set; } 同样表示这个属性可以被读取和写入。
public Animal(string name, int age)
{
Name = name;
Age = age;
}
解释:定义一个构造函数 Animal。构造函数是一个特殊的方法,在创建类的实例时调用。public 关键字表示这个构造函数可以被其他代码调用。参数 string name 和 int age 用于初始化 Name 和 Age 属性。
public virtual string 吃饭()
{
return "我要吃饭";
}
解释:定义一个公共的虚方法 吃饭,返回类型为 string。virtual 关键字表示这个方法可以在派生类中被重写。方法体返回一个字符串 "我要吃饭"。
public virtual string Makesound()
{
return "animal sound";
}
解释:定义另一个公共的虚方法 Makesound,返回类型为 string。方法体返回一个字符串 "animal sound"。
public override string ToString()
{
return $"{Name} (Age:{Age})";
}
解释:重写基类 Object 的 ToString 方法。override 关键字表示这是一个重写的方法。方法体返回一个格式化的字符串,包含 Name 和 Age 属性的值。$"{Name} (Age:{Age})" 是 C# 6.0 引入的字符串插值语法,允许在字符串中嵌入表达式。
2.DOG.cs
2.1 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AnimalNamespace
{
public class Dog:Animal
{
public Dog(string name, int age) : base(name, age) { }
public override string Makesound()
{
return "汪汪!";
}
public override string 吃饭()
{
return "我要啃骨头";
}
}
}
2.2 代码解释
public class Dog : Animal
{
解释:定义一个公共类 Dog,它继承自 Animal 类。public 关键字表示这个类可以被其他命名空间中的代码访问。: 表示继承关系,Dog 类继承自 Animal 类,意味着 Dog 类将具有 Animal 类的所有属性和方法。
public Dog(string name, int age) : base(name, age) { }
解释:定义一个构造函数 Dog,它接受两个参数 name 和 age,并将它们传递给基类 Animal 的构造函数。base(name, age) 调用基类的构造函数以初始化继承自基类的 Name 和 Age 属性。
public override string Makesound()
{
return "汪汪!";
}
解释:重写基类 Animal 的虚方法 Makesound。override 关键字表示这是一个重写的方法。这个方法返回一个字符串 "汪汪!"。
public override string 吃饭()
{
return "我要啃骨头";
}
解释:重写基类 Animal 的虚方法 吃饭。这个方法返回一个字符串 "我要啃骨头"。
3.CAT.cs
3.1 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AnimalNamespace
{
public class Cat:Animal
{
public Cat(string Name, int age):base(Name, age){ }
public override string Makesound()
{
return "喵喵";
}
}
}
3.2 代码解释
同DOG.cs
4.MainWindow.xaml.cs
4.1 代码
using System.ComponentModel;
using System.Text;
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;
using AnimalNamespace;
namespace WpfApp2
{
public partial class MainWindow : Window
{
List<Animal> Zoo;
private 我的实验 MyText;
public MainWindow()
{
InitializeComponent();
Zoo = new List<Animal>();
MyText=new 我的实验();
MyText.显示串 = "";
DataContext = new { 我的实验 = MyText };
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Dog x = new Dog("dog" + DateTime.Now.Second.ToString(), DateTime.Now.Second);
Zoo.Add(x);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Cat x = new Cat("cat" + DateTime.Now.Second.ToString(), DateTime.Now.Second);
Zoo.Add(x);
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
string 叫声 = "";
foreach (Animal animal in Zoo)
{
if (animal != null)
{
叫声+=animal .Name +":"+ animal.Makesound()+ ":"+animal.吃饭();
叫声 += Environment.NewLine;
}
}
MyText.显示串 = 叫声;
}
}
public class 我的实验 : INotifyPropertyChanged
{
private string _显示串;
public string 显示串
{
get { return _显示串; }
set
{
_显示串 = value;
OnPropertyChanged("显示串");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
4.2 代码解释
public partial class MainWindow : Window
{
解释:定义一个公共的部分类 MainWindow,继承自 Window 类。这个类是 WPF 应用程序的主窗口。
List<Animal> Zoo;
private 我的实验 MyText;
解释:定义一个 Zoo 列表,用于存储 Animal 类的实例。定义一个私有字段 MyText,类型为 我的实验,用于数据绑定。
public MainWindow()
{
InitializeComponent();
Zoo = new List<Animal>();
MyText = new 我的实验();
MyText.显示串 = "";
DataContext = new { 我的实验 = MyText };
}
解释:定义 MainWindow 的构造函数。
InitializeComponent():初始化组件,加载 XAML 中定义的 UI 元素。Zoo = new List<Animal>():初始化Zoo列表。MyText = new 我的实验():初始化MyText实例。MyText.显示串 = "":将MyText的显示串属性初始化为空字符串。DataContext = new { 我的实验 = MyText }:设置数据上下文,用于数据绑定。
private void Button_Click(object sender, RoutedEventArgs e)
{
Dog x = new Dog("dog" + DateTime.Now.Second.ToString(), DateTime.Now.Second);
Zoo.Add(x);
}
解释:定义一个按钮点击事件处理方法 Button_Click。
Dog x = new Dog("dog" + DateTime.Now.Second.ToString(), DateTime.Now.Second):创建一个新的Dog实例,名字包括当前秒数。Zoo.Add(x):将新创建的Dog实例添加到Zoo列表中。
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Cat x = new Cat("cat" + DateTime.Now.Second.ToString(), DateTime.Now.Second);
Zoo.Add(x);
}
解释:定义另一个按钮点击事件处理方法 Button_Click_1。
Cat x = new Cat("cat" + DateTime.Now.Second.ToString(), DateTime.Now.Second):创建一个新的Cat实例,名字包括当前秒数。Zoo.Add(x):将新创建的Cat实例添加到Zoo列表中。
private void Button_Click_2(object sender, RoutedEventArgs e)
{
string 叫声 = "";
foreach (Animal animal in Zoo)
{
if (animal != null)
{
叫声 += animal.Name + ":" + animal.Makesound() + ":" + animal.吃饭();
叫声 += Environment.NewLine;
}
}
MyText.显示串 = 叫声;
}
解释:定义第三个按钮点击事件处理方法 Button_Click_2。
string 叫声 = "":初始化一个空字符串叫声。foreach (Animal animal in Zoo):遍历Zoo列表中的每个Animal实例。if (animal != null):检查animal是否不为null。叫声 += animal.Name + ":" + animal.Makesound() + ":" + animal.吃饭():将animal的名字、叫声和吃饭行为添加到叫声字符串中。叫声 += Environment.NewLine:添加换行符。MyText.显示串 = 叫声:更新MyText的显示串属性。
public class 我的实验 : INotifyPropertyChanged
{
解释:定义一个公共类 我的实验,实现 INotifyPropertyChanged 接口。这个接口用于通知属性值的更改。
private string _显示串;
public string 显示串
{
get { return _显示串; }
set
{
_显示串 = value;
OnPropertyChanged("显示串");
}
}
解释:定义一个私有字段 _显示串 和一个公共属性 显示串。
get { return _显示串; }:返回_显示串的值。set { _显示串 = value; OnPropertyChanged("显示串"); }:设置_显示串的值,并调用OnPropertyChanged("显示串")方法通知属性值的更改。
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
解释:
public event PropertyChangedEventHandler PropertyChanged:定义一个PropertyChanged事件,用于通知属性值的更改。protected virtual void OnPropertyChanged(string propertyName):定义一个受保护的虚方法OnPropertyChanged,用于触发PropertyChanged事件。PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)):如果PropertyChanged事件不为空,则触发该事件,并传递propertyName参数。
5.MainWindow.xaml
5.1 代码
<Window x:Class="WpfApp2.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:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="DOG" HorizontalAlignment="Left" Height="67" Margin="71,49,0,0" VerticalAlignment="Top" Width="120" Click="Button_Click"/>
<Button Content="CAT" HorizontalAlignment="Left" Height="67" Margin="212,49,0,0" VerticalAlignment="Top" Width="120" Click="Button_Click_1"/>
<Button Content="MAKESOUND" HorizontalAlignment="Left" Height="67" Margin="355,49,0,0" VerticalAlignment="Top" Width="120" Click="Button_Click_2"/>
<TextBlock x:Name="OutputTextBlock" HorizontalAlignment="Left" Height="183" Margin="71,140,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="404" FontSize="16"
Text="{Binding 我的实验.显示串}" />
</Grid>
</Window>
5.2 代码解释
<Window x:Class="WpfApp2.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:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
解释:
<Window>标签定义了一个 WPF 窗口。x:Class="WpfApp2.MainWindow":指定这个窗口的关联类是WpfApp2.MainWindow。xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation":定义 XAML 的默认命名空间,用于 WPF 控件。xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml":定义 XAML 的 X 命名空间,用于 XAML 语言功能。xmlns:d="http://schemas.microsoft.com/expression/blend/2008":定义设计时支持的命名空间。xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006":定义标记兼容性的命名空间。xmlns:local="clr-namespace:WpfApp2":定义本地命名空间WpfApp2,用于引用同一个命名空间内的类型。mc:Ignorable="d":指示设计时命名空间中的内容在运行时可以忽略。Title="MainWindow":设置窗口的标题为 "MainWindow"。Height="450"和Width="800":设置窗口的高度为 450 像素,宽度为 800 像素。
<Grid>
<Button Content="DOG" HorizontalAlignment="Left" Height="67" Margin="71,49,0,0" VerticalAlignment="Top" Width="120" Click="Button_Click"/>
<Button Content="CAT" HorizontalAlignment="Left" Height="67" Margin="212,49,0,0" VerticalAlignment="Top" Width="120" Click="Button_Click_1"/>
<Button Content="MAKESOUND" HorizontalAlignment="Left" Height="67" Margin="355,49,0,0" VerticalAlignment="Top" Width="120" Click="Button_Click_2"/>
<TextBlock x:Name="OutputTextBlock" HorizontalAlignment="Left" Height="183" Margin="71,140,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="404" FontSize="16"
Text="{Binding 我的实验.显示串}" />
</Grid>
</Window>
解释:
-
<Grid>:定义一个网格布局容器,用于组织其子元素。 -
<Button>:定义一个按钮控件。Content="DOG":按钮上的文本为 "DOG"。HorizontalAlignment="Left":按钮水平左对齐。Height="67":按钮高度为 67 像素。Margin="71,49,0,0":按钮的外边距,分别是左、上、右、下(左边距 71 像素,上边距 49 像素)。VerticalAlignment="Top":按钮垂直顶部对齐。Width="120":按钮宽度为 120 像素。Click="Button_Click":单击按钮时调用Button_Click方法。
-
第二个
<Button>控件类似,只是内容为 "CAT",外边距不同(左边距 212 像素),单击事件处理方法为Button_Click_1。 -
第三个
<Button>控件内容为 "MAKESOUND",外边距不同(左边距 355 像素),单击事件处理方法为Button_Click_2。 -
<TextBlock>:定义一个文本块控件,用于显示文本。x:Name="OutputTextBlock":设置控件的名称为OutputTextBlock。HorizontalAlignment="Left":文本块水平左对齐。Height="183":文本块高度为 183 像素。Margin="71,140,0,0":文本块的外边距,分别是左、上、右、下(左边距 71 像素,上边距 140 像素)。TextWrapping="Wrap":文本自动换行。VerticalAlignment="Top":文本块垂直顶部对齐。Width="404":文本块宽度为 404 像素。FontSize="16":文本块的字体大小为 16 像素。Text="{Binding 我的实验.显示串}":通过数据绑定将我的实验类的显示串属性绑定到文本块的文本属性。
二、实验结果
在这个过程中我依次点击了2次DOG、1次CAT、1次DOG、1次CAT,最后点击MAKESOUND使它们发出相同的行为,结果如下。

总结
这个项目通过 WPF (Windows Presentation Foundation) 实现了一个简单的动物管理应用程序,具有以下功能:
-
界面布局:
- 主窗口包含三个按钮和一个文本块,用于用户交互和显示结果。
-
按钮功能:
- “DOG” 按钮:点击后创建一个新的
Dog对象,并将其添加到动物列表Zoo中。 - “CAT” 按钮:点击后创建一个新的
Cat对象,并将其添加到动物列表Zoo中。 - “MAKESOUND” 按钮:点击后遍历
Zoo列表,获取所有动物的名字、叫声和吃饭行为,并将这些信息显示在文本块中。
- “DOG” 按钮:点击后创建一个新的
-
数据绑定:
- 使用
INotifyPropertyChanged接口和数据绑定机制,实现数据的动态更新。具体来说,我的实验类包含一个显示串属性,当其值发生变化时,通过数据绑定更新显示在界面上的文本块。
- 使用
具体实现细节
-
Animal 类及其派生类:
Animal类是一个基类,包含Name和Age属性,以及虚方法Makesound()和吃饭()。Dog类和Cat类继承自Animal类,分别重写了Makesound()和吃饭()方法,提供各自特有的实现。
-
MainWindow 类:
- 定义了主窗口的构造函数,初始化组件、动物列表
Zoo和我的实验类的实例。 - 定义了三个按钮点击事件处理方法,分别用于添加
Dog和Cat对象,以及显示动物的名字、叫声和吃饭行为。
- 定义了主窗口的构造函数,初始化组件、动物列表
-
我的实验类:
- 实现
INotifyPropertyChanged接口,包含一个显示串属性,当其值改变时,触发PropertyChanged事件通知界面更新。
- 实现
-
XAML 布局:
- 使用 XAML 定义主窗口布局,包括三个按钮和一个文本块。
- 使用数据绑定机制,将
我的实验类的显示串属性绑定到文本块的Text属性,实现动态数据展示。
项目功能总结
- 添加动物:用户可以通过点击按钮向动物列表中添加
Dog和Cat对象,每个对象的名字包含当前秒数。 - 显示动物信息:点击“MAKESOUND”按钮后,遍历动物列表,显示每个动物的名字、叫声和吃饭行为。
- 数据绑定与动态更新:通过数据绑定机制和
INotifyPropertyChanged接口,确保界面上的文本块能动态显示最新的动物信息。










