C#集合初始化、类型推理、动态查找、可选参数、命名参数、WPF 样式,模板,触发器,值转换,触发器,动画、视图模型

在C#中,集合可以通过初始化器进行初始化

  • 这使得集合的创建和初始化变得更加简单和方便,下面是一些常用的集合初始化方法:
//List初始化
List<string> list = new List<string>{"one", "two", "three"};
//Dictionary初始化

Dictionary<int, string> dict = new Dictionary<int, string>{
    {1, "one"},
    {2, "two"},
    {3, "three"}
};
//HashSet初始化

HashSet<int> hashSet = new HashSet<int>{1, 2, 3, 4, 5};
//Queue初始化

Queue<string> queue = new Queue<string>(new[]{"one", "two", "three"});
//Stack初始化

Stack<string> stack = new Stack<string>(new[]{"one", "two", "three"});

以上是常见的几种集合初始化方式,使用集合初始化器可以快速、简单地初始化一个集合。

C#中的类型推理(Type Inference)

是指编译器在编译时自动推断变量类型的能力,而无需显式地指定类型。类型推理有助于简化代码,提高代码的可读性和可维护性。

  • C#中有两种类型推理方式:

var关键字

使用var关键字可以让编译器自动推断变量类型,如下所示:

var num = 10; // 推断出num为int类型
var name = "Alice"; // 推断出name为string类型
var list = new List<string>{"one", "two", "three"}; // 推断出list为List<string>类型

需要注意的是,使用var声明的变量必须在声明时进行初始化,因为编译器需要根据初始化表达式推断出变量的类型。

泛型类型推理
在C# 3.0中,引入了泛型类型推理(Generic Type Inference),它允许编译器自动推断泛型方法或泛型委托的类型参数。例如:

// 泛型方法
public static void Print<T>(T value) {
    Console.WriteLine(value);
}
// 调用泛型方法
Print(10); // 推断出T为int类型
Print("Hello"); // 推断出T为string类型
// 泛型委托
Func<int, string> func = x => x.ToString(); // 推断出Func<int, string>类型

需要注意的是,泛型类型推理只适用于方法或委托的参数列表中,而不适用于泛型类或结构体的类型参数。

C#动态查找

在C#中,动态查找(Dynamic Lookup)指的是在运行时通过反射或动态语言运行时(DLR)获取类型或成员信息的能力。通过动态查找,我们可以在运行时才确定对象的类型或成员,并且可以在不知道类型或成员名称的情况下进行访问。
动态查找有两种常用的方式:反射和动态语言运行时(DLR)。
反射
反射是指在运行时获取程序集、类型和成员信息的机制。使用反射可以在运行时动态地加载程序集,获取类型信息并创建类型实例,访问类型的成员(字段、属性、方法等)等。例如,下面的代码使用反射****获取类型信息和访问类型的成员

// 获取类型信息
Type type = typeof(MyClass);
// 创建类型实例object instance = Activator.CreateInstance(type);
// 访问字段
FieldInfo field = type.GetField("myField");
int value = (int)field.GetValue(instance);
// 调用方法
MethodInfo method = type.GetMethod("MyMethod");
method.Invoke(instance, null);

DLR

动态语言运行时(DLR)是指一个运行时库,它可以使C#具有像动态语言一样的行为。使用DLR,可以在运行时动态地解析和调用成员、处理运算符、构建表达式等。例如,下面的代码使用DLR访问类型的成员:

// 创建动态对象
dynamic obj = Activator.CreateInstance(typeof(MyClass));
// 访问字段
int value = obj.myField;
// 调用方法
obj.MyMethod();

需要注意的是,使用动态查找虽然方便,但也增加了代码的复杂性和运行时开销。因此,在性能要求较高的场景中,应尽量避免使用动态查找。

C#中的可选参数(Optional Parameters)

是指在方法或构造函数中,可以定义一些参数,这些参数在调用方法或构造函数时可以省略。可选参数可以让方法或构造函数的调用更加灵活和简洁,同时也可以提高代码的可读性和可维护性。
定义可选参数的方式如下:

public void MyMethod(int arg1, string arg2 = "default", bool arg3 = true) {
    // 方法体
}
//在上面的方法中,arg2和arg3是可选参数,它们的默认值分别为"default"和true。
//调用该方法时,可以省略这些可选参数:

MyMethod(10); // 等价于MyMethod(10, "default", true);
MyMethod(10, "hello"); // 等价于MyMethod(10, "hello", true);
MyMethod(10, "hello", false); // 调用MyMethod方法,并指定arg1=10, arg2="hello", arg3=false

需要注意的是,可选参数必须位于参数列表的末尾,并且所有参数必须具有默认值。如果省略了可选参数,则编译器会使用它们的默认值。在调用可选参数的方法或构造函数时,如果想指定某个可选参数的值,可以使用参数名来指定,例如:

MyMethod(10, arg3: false); // 指定arg1=10, arg3=false,使用arg2的默认值

需要注意的是,在使用可选参数时,应该考虑可读性和可维护性的平衡,不要过度使用可选参数,以免降低代码的可读性和可维护性。同时,应该避免在公共API中使用可选参数,以免给使用者带来困扰。

在C#中,命名参数(Named Parameters)

是指在方法或构造函数调用时,通过指定参数名来传递参数的值。使用命名参数可以让方法或构造函数调用更加灵活和易于理解,同时也可以提高代码的可读性和可维护性。
在调用带有命名参数的方法或构造函数时,可以使用以下方式指定参数名和参数值:

MyMethod(arg1: 10, arg2: "hello", arg3: true);

在上面的调用中,参数名和参数值之间使用冒号分隔,不同的参数之间使用逗号分隔。需要注意的是,命名参数可以与普通参数混合使用,但命名参数必须放在普通参数之后。
定义带有命名参数的方法或构造函数时,需要在参数前面加上参数名:

public void MyMethod(int arg1, string arg2, bool arg3) {
    // 方法体
}

需要注意的是,命名参数可以不按照定义时的顺序传递。例如,下面的调用是合法的:

MyMethod(arg3: true, arg1: 10, arg2: "hello");

另外,命名参数可以与可选参数一起使用。在这种情况下,可以通过省略参数名来使用默认值。例如,下面的调用是合法的:

MyMethod(arg1: 10, arg3: true); // 等价于MyMethod(10, arg2: "default", arg3: true);

需要注意的是,命名参数可以提高代码的可读性和可维护性,但也可能会使代码更加复杂和难以理解。在使用命名参数时,应该谨慎使用,只在必要的时候才使用。同时,在公共API中使用命名参数也应该小心,以免给使用者带来困扰。

假设有一个带有多个参数的方法,如下所示:

public void PrintPersonInfo(string name, int age, string address, string phoneNumber) {
    Console.WriteLine($"Name: {name}, Age: {age}, Address: {address}, Phone Number: {phoneNumber}");
}

在调用该方法时,如果只是按照参数的位置传递参数,很容易出错。例如,下面的代码可能会把参数传递错位:

PrintPersonInfo("Alice", 20, "123456789", "New York"); // 错误的参数顺序

为了避免这种错误,可以使用命名参数来指定参数名和参数值:

PrintPersonInfo(name: "Alice", age: 20, phoneNumber: "123456789", address: "New York"); // 正确的参数顺序

通过使用命名参数,不仅可以避免参数顺序错误,还可以使代码更加清晰易读。另外,如果有一些参数是可选的,也可以使用命名参数来指定需要的参数值。例如,可以定义一个可选参数address:

public void PrintPersonInfo(string name, int age, string phoneNumber, string address = "") {
    if (string.IsNullOrEmpty(address)) {
        Console.WriteLine($"Name: {name}, Age: {age}, Phone Number: {phoneNumber}");
    } else {
        Console.WriteLine($"Name: {name}, Age: {age}, Address: {address}, Phone Number: {phoneNumber}");
    }
}

在调用该方法时,可以使用命名参数来指定address参数的值,或者省略address参数使用默认值:

PrintPersonInfo(name: "Alice", age: 20, phoneNumber: "123456789"); // 不指定address参数,使用默认值
PrintPersonInfo(name: "Bob", age: 25, phoneNumber: "987654321", address: "Los Angeles"); // 指定address参数的值

通过使用命名参数和可选参数,可以使代码更加灵活和易于使用。但需要注意的是,在使用命名参数时应该谨慎使用,避免过度使用导致代码过于复杂难以维护。

WPF 样式,模板,触发器,值转换,触发器,动画

WPF中的样式,模板,触发器,值转换器,动画等是实现UI设计的关键组成部分,下面分别介绍一下它们的作用和使用方法。

  • 样式(Style)

样式是用于为WPF中的控件定义外观和行为的一种方式,它可以应用于单个控件或整个应用程序中的所有控件。可以在XAML中定义样式,也可以在代码中定义样式。样式通常包括控件的模板和属性值的集合。
在XAML中,可以使用Style元素定义样式,例如:

<Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="LightBlue"/>
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="Black"
                        BorderThickness="2"
                        CornerRadius="5"
                        Padding="5">
                    <ContentPresenter HorizontalAlignment="Center"
                                      VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

上面的代码定义了一个样式,将其应用于Button控件,设置了Background、FontSize和FontWeight属性,并定义了控件的模板,以Border和ContentPresenter元素为主体

  • 模板(Template)

模板是控件的可视化表示,定义了控件如何呈现。WPF控件的外观是由模板定义的。模板通常包括在样式中,但也可以作为单独的资源定义。模板使用控件的Template属性设置。
以下是一个简单的模板示例,用于自定义Button控件的外观:

<ControlTemplate x:Key="MyButtonTemplate" TargetType="{x:Type Button}">
    <Border BorderThickness="1" BorderBrush="Black" Background="LightGray">
        <ContentPresenter Margin="5"/>
    </Border>
</ControlTemplate>

上述模板定义了一个Button控件的模板,包括一个Border和一个ContentPresenter元素。控件的Template属性可以引用这个模板,例如:

<Button Content="My Button" Template="{StaticResource MyButtonTemplate}"/>
  • 触发器(Trigger)

触发器是一种在控件状态更改时执行动作的行为。例如,当控件的属性更改时,可以使用触发器更改控件的样式或模板。
以下是一个简单的触发器示例,用于在Button控件的IsMouseOver属性更改时更改控件的背景色:

<Style TargetType="{x:Type Button}">
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="LightBlue"/>
        </Trigger>
    </Style.Triggers>
</Style>
  • 样式(Style)

是一种定义一组控件通用属性的方式。可以在一个控件上定义一个样式,然后在其他控件上应用该样式,使这些控件具有相同的外观和行为。样式定义了一组属性的值,这些属性将被应用于控件的所有实例。
例如,可以定义一个名为“ButtonStyle”的样式,该样式为所有的按钮定义了一个蓝色背景、白色字体和边框。然后可以在多个按钮中使用该样式,而不必重复设置这些属性。
在XAML中,可以通过在Resources集合中定义样式来创建样式,如下所示:

<Window.Resources>
  <Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Blue"/>
    <Setter Property="Foreground" Value="White"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="BorderBrush" Value="Black"/>
  </Style>
 </Window.Resources>

该代码定义了一个名为“ButtonStyle”的样式,将其TargetType设置为Button。在该样式中,通过Setter元素设置了Background、Foreground、BorderThickness和BorderBrush等属性的值。
可以在控件上使用Style属性来应用样式,如下所示:

<Button Style="{StaticResource ButtonStyle}" Content="Click me"/>

这样,按钮将应用“ButtonStyle”样式中定义的属性。

  • 模板

模板(Template)是一种定义控件外观和行为的方式,可以用于自定义控件。在WPF中,控件的外观和行为都是通过模板来定义的。
模板通常包括一些XAML标记和样式,用于定义控件的外观和行为。在模板中可以定义控件的布局、背景、边框、文本等元素。
例如,可以为ListBox控件创建一个自定义模板,使它显示为一个带有圆角边框和阴影的列表框。
在XAML中,可以使用ControlTemplate元素来定义模板,如下所示:

<ControlTemplate TargetType="{x:Type ListBox}">
  <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="5" Background="White">
    <Grid>
      <ScrollViewer>
        <ItemsPresenter/>
      </ScrollViewer>
    </Grid>
  </Border>
</ControlTemplate>

该模板定义了一个带有圆角边框和阴影的列表框。在模板中,使用了Border元素作为列表框的容器,并使用了Grid和ScrollViewer等元素来定义列表框中的内容。
可以通过设置控件的Template属性来应用模板,如下所示:

<ListBox Template="{StaticResource ListBoxTemplate}">
  <ListBoxItem>Item 1</ListBoxItem>
  />

WPF中的样式、模板、触发器、值转换器、动画等是非常重要的概念,能够帮助我们快速开发出漂亮且具有交互性的应用程序。

  • 样式(Style):

WPF中的样式是一组属性和值的集合,可以被应用到控件上,以定义控件的外观和行为。样式通常包含一些触发器(Triggers)来改变控件在不同状态下的外观和行为。

  • 模板(Template):

WPF中的模板是一种定义控件外观的方式,可以自定义控件的各个部分的外观和布局。模板通常包含多个控件,它们会组成一个整体,呈现出控件的外观。

  • 触发器(Trigger):

WPF中的触发器用于在控件的属性值发生改变时触发某些操作。常见的触发器包括属性触发器、事件触发器和数据触发器等。

  • 值转换器(Value Converter):

WPF中的值转换器用于在绑定数据时对数据进行转换。比如,我们可以使用值转换器将字符串类型的数据转换成颜色或图片等其他类型的数据。

  • 动画(Animation):

WPF中的动画可以为控件属性的值设置动态变化的效果,使应用程序具有更好的交互性和视觉效果。WPF中的动画可以使用动画属性、故事板(Storyboard)和动画时钟(Animation Clock)等方式来实现。
总的来说,WPF中的样式、模板、触发器、值转换器和动画等技术是非常强大和灵活的,可以帮助我们轻松实现自定义控件和交互效果。同时,也需要深入理解其原理和使用方法,才能充分发挥其优势。

  • 样式:

我们可以使用样式来定义按钮(Button)控件的外观和行为。比如,我们可以设置按钮的背景颜色、边框样式、文字大小、对齐方式等属性,并定义按钮在不同状态下的样式。例如:

<Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Gray"/>
    <Setter Property="Foreground" Value="White"/>
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="FontSize" Value="20"/>
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                    <ContentPresenter Name="contentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter TargetName="border" Property="Background" Value="DarkGray"/>
                        <Setter TargetName="contentPresenter" Property="RenderTransform" >
                            <Setter.Value>
                                <TranslateTransform X="1" Y="1"/>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
 </Style>
  • 模板:

我们可以使用模板来自定义ListBox控件的外观。比如,我们可以设置每个ListBox项的样式和排列方式,以及滚动条的样式等属性。例如:

<Style TargetType="{x:Type ListBox}">
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Background" Value="White"/>
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBox}">
                <Border Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                    <Grid>
                        <ScrollViewer Name="scrollViewer" Focusable="False">
                            <StackPanel>
                                <ItemsPresenter/>
                            </StackPanel>
                        </ScrollViewer>
                        <ScrollBar Name="verticalScrollBar" Orientation="Vertical" Value="{TemplateBinding VerticalOffset}" Maximum="{TemplateBinding ScrollableHeight}" ViewportSize="{TemplateBinding ViewportHeight}" Height="{Binding ElementName=scrollViewer, Path=ViewportHeight}" Visibility="{Binding ElementName=scrollViewer, Path=ComputedVerticalScrollBarVisibility}" />
                        <ScrollBar Name="horizontalScrollBar" Orientation="Horizontal" Value="{TemplateBinding HorizontalOffset}" Maximum="{TemplateBinding ScrollableWidth}" ViewportSize="{TemplateBinding ViewportWidth}" Width="{Binding ElementName=scrollViewer, Path=ViewportWidth}" Visibility="{Binding ElementName=scrollViewer, Path=ComputedHorizontalScrollBarVisibility}" />
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    />
  • 动画

动画可以通过 WPF 中的 Storyboard 来实现。Storyboard 是一个用于控制动画的对象,可以包含一个或多个动画对象。
例如,可以通过以下代码来定义一个简单的 Storyboard,并将其应用于控件的属性:

<Window.Resources>
    <Storyboard x:Key="myAnimation">
        <DoubleAnimation From="0" To="100" Duration="0:0:2" 
                         Storyboard.TargetName="myRectangle" 
                         Storyboard.TargetProperty="Width" />
    </Storyboard>
    </Window.Resources>
    <Grid>
    <Rectangle x:Name="myRectangle" Width="50" Height="50" Fill="Red" />
    <Button Content="Animate" Click="Button_Click" />
    </Grid>

在这个例子中,定义了一个名为 myAnimation 的 Storyboard,其中包含了一个 DoubleAnimation 对象,用于将 myRectangle 控件的 Width 属性从 0 动态地变化到 100,持续时间为 2 秒钟。
在按钮的 Click 事件中,可以通过以下代码来启动动画:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Storyboard sb = (Storyboard)this.Resources["myAnimation"];
    sb.Begin();
}

在这个例子中,通过代码获取名为 myAnimation 的 Storyboard 对象,并调用其 Begin 方法启动动画。
除了 DoubleAnimation,WPF 还提供了多种不同类型的动画,包括 ColorAnimation、PointAnimation、ThicknessAnimation 等,可以通过控制不同的属性来实现各种动画效果。
此外,WPF 还提供了多种不同类型的触发器(Trigger),如 EventTrigger、PropertyTrigger、DataTrigger 等,用于在不同条件下触发控件的状态变化和动画效果,可以大大增强 WPF 应用程序的交互性和视觉效果。同时,WPF 还提供了值转换器(ValueConverter)和多种不同类型的动画效果,如 ColorAnimation、PointAnimation、ThicknessAnimation 等,可以帮助开发人员更加方便地实现复杂的视觉效果和动画效果。

下是一个使用 Setter 设置 ItemTemplate 的示例:

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}" />
                <TextBlock Text="{Binding Age}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.Items>
        <local:Person Name="Tom" Age="18" />
        <local:Person Name="Jerry" Age="20" />
    </ListBox.Items>
    </ListBox>

在这个示例中,定义了一个 ListBox 控件,并通过 Setter 的方式设置了 ItemTemplate 的值为 DataTemplate。在 DataTemplate 中,定义了一个 StackPanel,其中包含两个 TextBlock 控件,用于显示 Person 对象的 Name 和 Age 属性。在 ListBox.Items 中添加了两个 Person 对象,用于测试显示效果。
通过这种方式,可以方便地设置控件的属性,同时可以使用 WPF 提供的数据绑定功能,将数据与界面进行绑定,使界面更加灵活和易于维护。

WPF 用户控件是一种自定义控件,可以用于创建自定义界面和功能模块。它允许开发人员使用 XAML 和 C# 或 VB.NET 等编程语言来创建自定义控件,以满足特定的业务需求和设计要求。
创建 WPF 用户控件的基本步骤如下:
创建一个新的 WPF 用户控件项目。
在 XAML 文件中定义控件的布局和样式,可以使用其他控件和数据绑定等 WPF 技术来扩展用户控件的功能。
在用户控件的代码文件中添加控件的行为和事件处理逻辑。
在其他 WPF 界面中使用该控件。
下面是一个简单的示例,演示如何创建一个 WPF 用户控件:

<!-- MyUserControl.xaml -->
<UserControl x:Class="WpfApp1.MyUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <TextBlock Text="Hello, World!" FontSize="24" />
    </Grid></UserControl>
// MyUserControl.xaml.csusing System.Windows.Controls;
namespace WpfApp1
{
    public partial class MyUserControl : UserControl
    {
        public MyUserControl()
        {
            InitializeComponent();
        }
    }
}

WPF视图模型是指在WPF应用程序中用于数据绑定的中间层。它充当了视图和模型之间的桥梁,负责处理数据的转换和业务逻辑。视图模型通常实现了INotifyPropertyChanged接口,以便在属性值发生更改时通知视图更新。视图模型还可以实现ICommand接口,以便处理用户输入和交互。
在MVVM(Model-View-ViewModel)架构中,视图模型是其中的核心部分,负责管理视图所需的数据和逻辑。视图模型的主要职责包括:
1.封装业务逻辑和数据操作,将数据从模型中提取出来,并将其格式化为视图可以显示的形式。
2.向视图公开绑定的属性,使视图可以使用数据绑定将其绑定到这些属性。
3.向视图公开命令,以便处理用户输入和交互。
4.提供通知机制,以便在属性值更改时通知视图更新。
视图模型可以包含许多不同类型的属性,例如布尔、字符串、数字、对象等等。在WPF应用程序中,视图模型通常使用ObservableCollection类来表示集合数据。此外,视图模型通常还包含事件和委托,以便响应用户交互和处理其他行为。
视图模型的实现可以采用各种技术,例如基于类的实现、基于接口的实现或使用框架和库。一些流行的WPF视图模型框架包括MVVM Light、Prism和Caliburn.Micro。

假设我们有一个名为Person的模型类,其中包含一个字符串类型的Name属性和一个整数类型的Age属性。我们可以创建一个名为PersonViewModel的视图模型类,将Person对象转换为视图所需的格式:

public class PersonViewModel : INotifyPropertyChanged
{
    private Person person;

    public string Name
    {
        get { return person.Name; }
        set
        {
            if (person.Name != value)
            {
                person.Name = value;
                OnPropertyChanged("Name");
            }
        }
    }

    public int Age
    {
        get { return person.Age; }
        set
        {
            if (person.Age != value)
            {
                person.Age = value;
                OnPropertyChanged("Age");
            }
        }
    }

    public PersonViewModel(Person person)
    {
        this.person = person;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

在这个例子中,PersonViewModel类包含了两个公共属性:Name和Age。这些属性使用Person对象的相应属性来返回值,并在值发生更改时触发PropertyChanged事件通知视图更新。我们还可以在PersonViewModel中添加其他属性和方法来处理业务逻辑和数据转换。最后,我们可以在XAML中使用数据绑定将视图绑定到PersonViewModel的属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值