WPF学习(2)--类与类的继承2-在窗口的实现

一、代码分析

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
    {

解释:定义一个公共类 Animalpublic 关键字表示这个类可以被其他命名空间中的代码访问。

        public string Name { get; set; }

解释:定义一个公共属性 Namestring 是数据类型,表示这个属性存储字符串。{ get; set; } 是属性访问器,表示这个属性可以被读取和写入。

        public int Age { get; set; }

解释:定义一个公共属性 Ageint 是数据类型,表示这个属性存储整数。{ get; set; } 同样表示这个属性可以被读取和写入。

        public Animal(string name, int age)
        {
           Name = name;
           Age = age;
        }

解释:定义一个构造函数 Animal。构造函数是一个特殊的方法,在创建类的实例时调用。public 关键字表示这个构造函数可以被其他代码调用。参数 string nameint age 用于初始化 NameAge 属性。

        public virtual string 吃饭()
        {
            return "我要吃饭";
        }

解释:定义一个公共的虚方法 吃饭,返回类型为 stringvirtual 关键字表示这个方法可以在派生类中被重写。方法体返回一个字符串 "我要吃饭"

        public virtual string Makesound()
        {
            return "animal sound";
        }

解释:定义另一个公共的虚方法 Makesound,返回类型为 string。方法体返回一个字符串 "animal sound"

        public override string ToString()
        {
            return $"{Name} (Age:{Age})";
        }

解释:重写基类 ObjectToString 方法。override 关键字表示这是一个重写的方法。方法体返回一个格式化的字符串,包含 NameAge 属性的值。$"{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,它接受两个参数 nameage,并将它们传递给基类 Animal 的构造函数。base(name, age) 调用基类的构造函数以初始化继承自基类的 NameAge 属性。

        public override string Makesound()
        {
            return "汪汪!";
        }

解释:重写基类 Animal 的虚方法 Makesoundoverride 关键字表示这是一个重写的方法。这个方法返回一个字符串 "汪汪!"

        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) 实现了一个简单的动物管理应用程序,具有以下功能:

  1. 界面布局

    • 主窗口包含三个按钮和一个文本块,用于用户交互和显示结果。
  2. 按钮功能

    • “DOG” 按钮:点击后创建一个新的 Dog 对象,并将其添加到动物列表 Zoo 中。
    • “CAT” 按钮:点击后创建一个新的 Cat 对象,并将其添加到动物列表 Zoo 中。
    • “MAKESOUND” 按钮:点击后遍历 Zoo 列表,获取所有动物的名字、叫声和吃饭行为,并将这些信息显示在文本块中。
  3. 数据绑定

    • 使用 INotifyPropertyChanged 接口和数据绑定机制,实现数据的动态更新。具体来说,我的实验 类包含一个 显示串 属性,当其值发生变化时,通过数据绑定更新显示在界面上的文本块。

具体实现细节

  1. Animal 类及其派生类

    • Animal 类是一个基类,包含 NameAge 属性,以及虚方法 Makesound()吃饭()
    • Dog 类和 Cat 类继承自 Animal 类,分别重写了 Makesound()吃饭() 方法,提供各自特有的实现。
  2. MainWindow 类

    • 定义了主窗口的构造函数,初始化组件、动物列表 Zoo我的实验 类的实例。
    • 定义了三个按钮点击事件处理方法,分别用于添加 DogCat 对象,以及显示动物的名字、叫声和吃饭行为。
  3. 我的实验类

    • 实现 INotifyPropertyChanged 接口,包含一个 显示串 属性,当其值改变时,触发 PropertyChanged 事件通知界面更新。
  4. XAML 布局

    • 使用 XAML 定义主窗口布局,包括三个按钮和一个文本块。
    • 使用数据绑定机制,将 我的实验 类的 显示串 属性绑定到文本块的 Text 属性,实现动态数据展示。

项目功能总结

  • 添加动物:用户可以通过点击按钮向动物列表中添加 DogCat 对象,每个对象的名字包含当前秒数。
  • 显示动物信息:点击“MAKESOUND”按钮后,遍历动物列表,显示每个动物的名字、叫声和吃饭行为。
  • 数据绑定与动态更新:通过数据绑定机制和 INotifyPropertyChanged 接口,确保界面上的文本块能动态显示最新的动物信息。
  • 38
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,这里我可以给你一个WPF使用MvvmLight实现MVVM的工程实例。 首先,你需要在Visual Studio中安装MvvmLight框架。可以通过NuGet来安装MvvmLight库,具体步骤如下: 1. 在Visual Studio中打开你的WPF工程。 2. 在Solution Explorer窗口中右键单击工程,选择“Manage NuGet Packages”。 3. 在“NuGet Package Manager”窗口中,在搜索框中输入“MvvmLight”,选择“MvvmLight”并安装。 接下来,我们就可以开始实现MVVM模式了。 1. 创建一个新的ViewModel继承自ViewModelBase。 ```csharp using GalaSoft.MvvmLight; public class MainViewModel : ViewModelBase { //ViewModel的属性和命令 } ``` 2. 在ViewModel中实现需要绑定的属性和命令。 ```csharp private string _message; public string Message { get { return _message; } set { if (_message != value) { _message = value; RaisePropertyChanged(() => Message); } } } private RelayCommand _showMessageCommand; public RelayCommand ShowMessageCommand { get { if (_showMessageCommand == null) { _showMessageCommand = new RelayCommand(() => { MessageBox.Show(Message); }); } return _showMessageCommand; } } ``` 3. 在View中绑定ViewModel的属性和命令。 ```xaml <Window x:Class="WpfApp1.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:WpfApp1" xmlns:vm="clr-namespace:WpfApp1.ViewModel" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.DataContext> <vm:MainViewModel /> </Window.DataContext> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <TextBox Text="{Binding Message, UpdateSourceTrigger=PropertyChanged}" /> <Button Grid.Row="1" Content="Show Message" Command="{Binding ShowMessageCommand}" /> </Grid> </Window> ``` 在这个例子中,我们创建了一个MainViewModel,其中包含了一个Message属性和一个ShowMessageCommand命令。在View中,我们使用DataContext将ViewModel实例与View绑定,并使用Binding将ViewModel的属性和命令绑定到View上。 这样,我们就成功地使用MvvmLight实现了MVVM模式。当用户在TextBox中输入文字并点击Button时,将会弹出一个对话框显示用户输入的文字。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值