- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
我们把世界看错,反说它欺骗了我们。 --飞鸟集 。
相较而言,命令对我来说是一个新概念,因为在 Winform 中压根没有所谓的命令这个概念🥲。从文字角度理解,"命令"可以指代一种明确的指令或要求,用于向某个实体传达特定的操作或行为。它可以是一个动词性的词语,表示对某个对象或主体的要求或指示。命令通常具有明确的目标和执行内容,它告诉接收者要执行什么操作,并在某种程度上对行为进行约束.
在软件开发中,"命令"是一种设计模式,它描述了将操作封装为对象的方法,以便在不同的上下文中使用和重用。这种命令模式通过将请求和操作封装到一个命令对象中,使得发送者和接收者之间解耦,从而实现了更灵活和可扩展的设计。在这种模式下,命令对象充当了发送者和接收者之间的中间媒介,接收者通过执行命令对象来完成特定的操作.
在提到命令的时候,我们通常拿它来和事件作比较。我们都知道, WPF 里已经有了路由事件,比如按钮在被点击以后做出的反应(直接事件),我们一般会通过 Button 的 Click 新建一个事件,然后在这个事件里面写一些业务代码:
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("You click me.");
}
当我们运行程序点击按钮时, Button_Click 事件会被驱动响应点击的动作弹出一个消息对话框,没有问题对吧。我们都知道,在早期的 GUI 框架中,应用程序的外观和行为方式之间没有真正的分离,回到这里也一样,将业务代码直接写在事件处理程序中会导致界面和业务逻辑紧密耦合在一起,使得两者难以分离和独立变更。实际开发中,我们会给按钮一个特定功能,当按钮的功能发生变化时,我们需要在 UI 界面中修改与这个功能所绑定的东西,同时也需要调整业务代码,这就导致了界面元素(外观)和业务逻辑(行为)混在一起,使得按钮的 XAML 代码既承担了外观的定义,又承担了业务逻辑的实现。此外,假设我们有很多个一样的按钮,都需要在用户点击按钮后为它提供相同的功能,通过上述面的方法,当这个功能发生改变时,我们就需要调正每一个涉及到的按钮以及相应的事件。为了解决这个问题, WPF 提供了命令机制(Command),可以将按钮的行为与其外观进行分离.
命令(Command)在 WPF 中是一种用于处理用户界面交互的机制,它们提供了一种在界面元素(UI)和后台逻辑之间进行 解耦 的方式,使得交互操作可以以一种 统一的、可重用的 方式进行处理。 WPF 命令的概念和实现是基于 MVVM(Model-View-ViewModel) 架构模式的,它使得界面元素的交互操作可以通过命令对象进行管理和处理,而不需要直接在界面代码中编写事件处理程序.
通过使用命令,我们能够更好地组织和管理界面交互行为,使得代码结构清晰,易于维护和扩展。同时,命令还提供了一些额外的功能,如参数传递、命令的可用性控制等,使得我们能够更灵活地处理用户的操作.
事件和命令:
事件是与用户动作进行联动的,而命令是那些想要与界面分离的动作,比如常见的复制粘贴命令,当我们点击一个具有 复制 功能的按钮时,相当于我们通过点击的这个动作触发了一个复制的命令,这样做的好处就是 - 界面的交互操作变得简单、代码可重用性提高,在不破坏后台逻辑的情况下可以更加灵活的控制用户界面.
WPF 命令模型主要包含以下几个基本元素:
命令(Command) :指的是实现了 ICommand 接口的类,例如 RoutedCommand 类及其子类 RoutedUICommand 类,一般不包含具体逻辑.
命令源(Command Source) :即命令的发送者,指的是实现了 ICommandSource 接口的类。像 Button 、 MenuItem 等界面元素都实现了这个接口,单击它们都会执行绑定的命令.
命令目标(Command Target) :即命令的接受者,指的是实现了 IInputElement 接口的类.
命令关联(Command Binding) :即将一些外围逻辑和命令关联起来.
借用刘老师的图来看一下他们的关系
ICommand 接口,包含一个事件两个方法:
public interface ICommand
{
//
// 摘要:
// 当出现影响是否应执行该命令的更改时发生。
event EventHandler CanExecuteChanged;
// 摘要:
// 定义用于确定此命令是否可以在其当前状态下执行的方法。
//
// 参数:
// parameter:
// 此命令使用的数据。如果此命令不需要传递数据,则该对象可以设置为 null。
//
// 返回结果:
// 如果可以执行此命令,则为 true;否则为 false。
bool CanExecute(object parameter);
//
// 摘要:
// 定义在调用此命令时调用的方法。
//
// 参数:
// parameter:
// 此命令使用的数据。如果此命令不需要传递数据,则该对象可以设置为 null。
void Execute(object parameter);
}
反过来看:
Execute - 执行某个动作 。
CanExecute - 能不能执行动作 。
CanExecuteChanged - 命令状态发生变化是响应的事件 。
通过实现 ICommand 接口,我们可以创建自定义的命令对象,并将其与界面元素进行绑定。这样,界面元素就可以与命令相关联,通过调用命令的 Execute 方法来执行具体的操作,而无需直接编写事件处理程序.
下面我们试着用命令的方式来实现上面的点击事件,并逐步理解模型中的内容。我们新建一个类 MainViewModel 来提供我们需要的功能方法:
using System.Windows;
namespace WPFDemo
{
public class MainViewModel
{
public void ShowInfo()
{
MessageBox.Show("You click me.");
}
}
}
ShowInfo() 这个时候跟 UI 界面是分开的对吧,有了方法之后,我们可以说 MainViewModel 中的 ShowInfo 就命令了吗,根据模型来看显然还不行。继续走,写一个实现 ICommand 接口但不带具体逻辑的类,比如 CustomCommand
using System;
using System.Windows.Input;
namespace WPFDemo
{
public class CustomCommand : ICommand
{
private readonly Action _execute;
public CustomCommand(Action execute)
{
_execute = execute;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
// 在这里实现命令的可执行逻辑
return true; // 默认返回true,表示命令可执行
}
public void Execute(object parameter)
{
// 在这里实现命令的执行逻辑
_execute?.Invoke();
}
}
}
之后在 MainViewModel 类中需要添加一个公共属性来暴露 CustomCommand 实例作为 ShowInfoCommand ,以便在 XAML 中进行绑定,
using System.Windows;
namespace WPFDemo
{
public class MainViewModel
{
public CustomCommand ShowInfoCommand { get; set; }
public MainViewModel()
{
ShowInfoCommand = new CustomCommand(ShowInfo);
}
public void ShowInfo()
{
MessageBox.Show("You click me.");
}
}
}
最后,将 CustomCommand 实例与界面元素进行绑定:
<Window x:Class="WPFDemo.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:local="clr-namespace:WPFDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Window.Resources>
<local:MainViewModel x:Key="ViewModel" />
</Window.Resources>
<Grid>
<Button Command="{Binding ShowInfoCommand}" Content="Click Me" DataContext="{StaticResource ViewModel}" />
</Grid>
</Window>
设置数据上下文也可以在后台代码中完成 。
回到命令模型上来,梳理以下对应关系:
CustomCommand
类本身是一个命令对象( ICommand
),它实现了命令接口,包括 Execute
和 CanExecute
方法。这个命令对象是命令模式中的 "具体命令"。 MainViewModel
类作为命令的执行者(或者称为命令目标),其中包含了 ShowInfo
方法。在命令模式中,执行者负责实际执行命令所需的操作。在我们的示例中, ShowInfo
方法是具体执行的业务逻辑。 XAML
中,我们使用 CommandBinding
将按钮的 Click
事件与 ShowInfoCommand
关联起来。这个关联是通过在 Window
或 UserControl
的 CommandBindings
集合中添加一个新的 CommandBinding
对象来完成的。这个 CommandBinding
指定了 ShowInfoCommand
作为命令和 MainViewModel
作为命令的执行者。 注意:Command属性仅仅作为Click行为的绑定,其他行为,如鼠标移入、移出。。。等行为,要使用另外的 MVVM 方式进行绑定.
最后,梳理下程序结构,可以看到,我们分别在 MainViewModel.cs 和 MainWindow.xaml 中书写业务代码和逻辑.
在 WPF 中,实现属性的通知更改是通过实现 INotifyPropertyChanged 接口来实现的。这个接口定义了一个 PropertyChanged 事件,当属性的值发生变化时,可以通过触发该事件来通知界面进行更新.
在进行演示之前,先来看看我们上面所使用的例子能否像之前学习的绑定一样实现自动更新,按照业务分离的逻辑,我们在 MainViewModel.cs 中添加一个 Name 字段并在页面进行绑定.
MainViewModel.cs :
using System.Windows;
namespace WPFDemo
{
public class MainViewModel
{
public CustomCommand ShowInfoCommand { get; set; }
public string Name { get; set; }
public MainViewModel()
{
Name = "狗熊岭第一狙击手";
ShowInfoCommand = new CustomCommand(ShowInfo);
}
public void ShowInfo()
{
Name = "光头强";
MessageBox.Show("You click me.");
}
}
}
MainWindow.xaml :
<Window x:Class="WPFDemo.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:local="clr-namespace:WPFDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<StackPanel>
<Button Command="{Binding ShowInfoCommand}" Content="Click Me" />
<TextBox Text="{Binding Name}" />
</StackPanel>
</Grid>
</Window>
之前 xaml 中的数据上下文不太好,需要在每个控件中都定义一次😎 。
上面的代码中,我们将 Name 绑定到了 TextBox 的文本中,并在点击按钮是改变 Name 的值,如果它自己可以通知更改,自动更新的话那么在 Name 变化的时候文本也应该变化,对吧。我们运行试一下:
可以看到 Name 的变化时 Text 并没有随之变化,这说明 Name 发生改变以后并没有通知 Text 也进行变化。如果你喜欢捣鼓的话,可以看看 Text 如果被修改以后 Name 会不会变化.
回到正题,上文提到过,实现属性的通知更改是通过实现 INotifyPropertyChanged 接口来实现的,我们来对自定义的 MainViewModel.cs 稍作修改实现属性的通知更改:
using System.ComponentModel;
using System.Windows;
namespace WPFDemo
{
public class MainViewModel : INotifyPropertyChanged
{
public CustomCommand ShowInfoCommand { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged(nameof(Name));
}
}
private void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public MainViewModel()
{
Name = "狗熊岭第一狙击手";
ShowInfoCommand = new CustomCommand(ShowInfo);
}
public void ShowInfo()
{
Name = "光头强";
MessageBox.Show("You click me.");
}
}
}
💭 nameof(Name) 是C# 6.0 引入的一个语法糖,它可以在编译时获取属性、方法、字段、类型等成员的名称作为一个字符串.
在 WPF 中, nameof(Name) 用于在属性更改通知中指定属性的名称。它的作用是避免硬编码属性名称,从而减少在重构过程中出现由于重命名属性而导致的错误.
修改过后, MainViewModel 类实现了 INotifyPropertyChanged 接口,并在 Name 属性的 setter 中进行了属性更改通知。当 Name 属性的值发生变化时,会触发 PropertyChanged 事件,通知界面进行更新.
在实现通知更改的方式中,可以将通知更改的逻辑定义在一个基类中,例如 ViewModelBase 类。这个基类可以包含通用的属性更改通知实现,以便其他具体的视图模型类可以继承该基类并重用这些通知更改的功能.
以下是一个简单的示例,展示了如何在 ViewModelBase 类中实现通知更改:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WPFDemo
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
在上面的代码中, ViewModelBase 类实现了 INotifyPropertyChanged 接口,并提供了 OnPropertyChanged 方法用于触发属性更改通知事件,并将属性名称作为参数传递.
默认情况下, CallerMemberName 特性用于自动获取调用该方法的成员的名称,并作为属性名称传递.
通过继承 ViewModelBase 类,并使用 OnPropertyChanged 方法来设置属性,可以简化视图模型类中属性更改通知的实现:
MainViewModel.cs :
using System.Windows;
namespace WPFDemo
{
public class MainViewModel : ViewModelBase
{
public CustomCommand ShowInfoCommand { get; set; }
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged();
}
}
private string _description;
public string Description
{
get { return _description; }
set { _description = value; OnPropertyChanged(); }
}
public MainViewModel()
{
Name = "狗熊岭第一狙击手";
Description = "光头强";
ShowInfoCommand = new CustomCommand(ShowInfo);
}
public void ShowInfo()
{
Name = "光头强";
Description = "狗熊岭第一突破手,麦克阿瑟如是说。";
MessageBox.Show("You click me.");
}
}
}
在这个示例中, MainViewModel 类继承了 ViewModelBase 类,并使用 OnPropertyChanged 方法来设置 Name 属性。当 Name 属性的值发生更改时, SetProperty 方法会自动处理属性更改通知的逻辑,无需手动触发事件或编写重复的代码.
通过将通知更改的实现定义在基类中,可以实现更简洁、可维护和可重用的代码,避免在每个具体的视图模型类中重复编写通知更改的逻辑.
有时候我们需要在执行命令时传递参数。在WPF中,可以使用 CommandParameter 属性来传递参数给命令.
CommandParameter 是一个附加属性,可以将任意对象指定为命令的参数。当命令执行时,命令的 Execute 方法会接收到该参数,并可以在命令处理逻辑中使用它.
以下是一个示例,展示如何在 XAML 中为命令指定 CommandParameter :
<Button Content="Click Me" Command="{Binding MyCommand}" CommandParameter="Hello, World!" /> 。
在这个示例中,我们将 Button 的 Command 属性绑定到 MyCommand 命令。同时,我们通过 CommandParameter 属性指定了一个字符串参数 "Hello, World!" 。当点击按钮时,该参数将传递给 MyCommand 命令的 Execute 方法.
在命令的执行逻辑中,可以通过命令参数来获取传递的值。以下是一个简单的命令类示例:
CustomCommand.cs :
using System;
using System.Windows.Input;
namespace WPFDemo
{
public class CustomCommand : ICommand
{
private readonly Action<object> _execute;
public CustomCommand(Action<object> execute)
{
_execute = execute;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
// 在这里实现命令的可执行逻辑
return true; // 默认返回true,表示命令可执行
}
public void Execute(object parameter)
{
// 在这里实现命令的执行逻辑
_execute?.Invoke(parameter as string);
}
}
}
CustomCommand 类接受一个 Action<object> 类型的参数,在构造函数中将传递的方法保存到 _execute 字段中。然后,在 Execute 方法中,通过调用 _execute?.Invoke(parameter) 来执行传递的方法,并将 parameter 作为参数传递给该方法.
这样,当你在 MainViewModel 中创建 CustomCommand 实例时,可以将 ShowInfo 方法作为参数传递进去, 。
MainViewModel.cs
using System.Windows;
namespace WPFDemo
{
public class MainViewModel
{
public CustomCommand ShowInfoCommand { get; set; }
public MainViewModel()
{
ShowInfoCommand = new CustomCommand(ShowInfo);
}
public void ShowInfo(object parameter)
{
MessageBox.Show(parameter as string);
}
}
}
那么 ShowInfo(object parameter) 的参数从哪里来呢 - CommandParameter 附加属性:
<Window x:Class="WPFDemo.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:local="clr-namespace:WPFDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<StackPanel>
<Button Command="{Binding ShowInfoCommand}" Content="Click Me" CommandParameter="Hello, World!" />
</StackPanel>
</Grid>
</Window>
这样看上去可能比较蠢,我们可以些微调整一下在页面中完成显示内容的修改,代码就不贴了,大家应该知道:
通过命令参数,可以实现更灵活的命令处理逻辑,根据传递的参数来执行不同的操作。同时,使用命令参数也可以实现与界面元素的交互,例如根据按钮的点击位置传递坐标信息等.
在文章开篇介绍命令时我们就有提到过 WPF 命令的概念和实现是基于 MVVM(Model-View-ViewModel) 架构模式的,而且从后续编码以及项目结构也可以看出来示例确实涉及了 MVVM(Model-View-ViewModel) 的思想,下边我们来看一下具体什么是 MVVM 以及一些主流的 MVVM 框架的引用与使用方法.
MVVM 是一种软件架构模式,是 Model (数据类型), View (界面), ViewModel (数据与界面之间的桥梁)的缩写,旨在将用户界面的逻辑与业务逻辑分离,以提高代码的可维护性、可测试性和可扩展性.
MVVM 模式由以下三个核心组件组成:
XAML
文件,描述了用户界面的布局和外观。视图应该只关注外观和布局,而不涉及具体的业务逻辑。 MVVM 模式的优势在于它实现了界面逻辑和业务逻辑的分离,使得代码更加清晰、可维护和可测试,视图和视图模型的解耦使得可以独立开发和测试它们,同时也提供了更好的可扩展性,使得可以在不影响视图的情况下修改和增加业务逻辑.
总结起来, MVVM 模式通过将用户界面、数据和业务逻辑进行分离,提供了一种结构化的方式来开发和维护 WPF 应用程序。它使得开发人员能够更好地管理代码,并使得应用程序更具可扩展性和可测试性.
构建 MVVM 框架时有自己造轮子的,就像上面命令的示例中那样;也有使用现成的开源项目,下面例举两个比较常见的现成的框架包.
项目地址: mvvmlight 。
MVVM Light is not maintained anymore. Over the years, thousands of users have found this project useful with millions of downloads. We are truly overwhelmed by the kindness shown by a huge amount of members of this awesome community. Thanks so much for making this little project so popular and for making it all worthwhile. 。
MvvmLight 不再维护。多年来,成千上万的用户发现这个项目有数百万的下载量。我们真的被这个令人敬畏的社区的大量成员所表现出的善意所淹没。非常感谢你让这个小项目如此受欢迎,让它一切都变得有价值.
We strongly recommend looking into the Microsoft MVVM Toolkit , an open source project from the Windows Community Toolkit, as the successor of MVVM Light. 。
我们强烈建议研究Microsoft MVVM Toolkit,这是Windows社区工具包中的一个开源项目,作为MVVM Light的继任者.
MvvmLight 是一个轻量级的 MVVM 框架,它提供了许多用于实现 MVVM 模式的工具和功能。以下是 MvvmLight 的一些主要特点和组成部分:
ViewModel
基类: MvvmLight
提供了一个称为 ViewModelBase
的基类,用于派生自定义的视图模型类。这个基类实现了 INotifyPropertyChanged
接口,简化了属性更改通知的实现,并提供了一些其他实用的功能。 MvvmLight
提供了一个事件聚合器,用于实现视图模型之间的松耦合通信。视图模型可以发布事件,其他视图模型可以订阅并响应这些事件,实现了解耦的消息传递机制。 MvvmLight
提供了 RelayCommand
类,它是一个通用的实现了 ICommand
接口的命令类。通过使用 RelayCommand
,开发人员可以轻松地在视图模型中定义和执行命令,并与视图进行绑定。 MvvmLight
提供了一个消息传递机制,允许视图模型之间进行简单的消息通信。开发人员可以发送消息并订阅消息,以实现视图模型之间的通信和交互。 MvvmLight
提供了一个简单的服务定位器,用于解耦视图模型和具体的服务实现。通过使用服务定位器,视图模型可以轻松地获取所需的服务实例,而不需要直接实例化服务类。 MvvmLight 是一个功能丰富且易于使用的 MVVM 框架,它提供了许多有用的工具和功能,帮助开发人员更轻松地实现 MVVM 模式,接下来我们试一试将 MvvmLight 框架应用在我们昨天的例子中.
在项目中添加 MvvmLight 的NuGet包,以便引入 MvvmLight 框架的相关组件和功能,对应版本安装就行了,注意区分自己的项目是在 .Net Framework 框架下还是 .Net Core :
安装完以后可以看到,项目的结构会发生些许变化,它会自动创建了一个名为 ViewModel 的文件夹以及 MainViewModel.cs 、 ViewModelLocator.cs 文件,同时 App.xaml 文件也会发生变化:
MainViewModel.cs - 继承自由 MvvmLight 框架提供的 ViewModelBase 类, ViewModelBase 类又继承类 ObservableObject ,同时实现了 ICleanup 接口,而 ObservableObject 类实现了 INotifyPropertyChanged 接口,用于通知属性的改变,需要时调用 RaisePropertyChanged() 即可.
ViewModelLocator.cs - 文件中只有一个 ViewModelLocator 类,类中包括一个构造函数、一个类型为 MainViewModel 的 Main 属性、以及一个静态的 Cleanup 函数。在构造函数中,创建了一个 SimpleIoc 类型的单实例,用于注册 MainViewModel ,然后用 ServiceLocator 对这个 SimpleIoc 类型的单实例进行包裹,方便统一管理.
App.xaml 文件变化 - ViewModelLocator 类被生成资源字典并加入到了全局资源.
DataContext="{Binding Main, Source={StaticResource Locator}}"
安装完成以后,我们把之前我们自造的 MVVM 模式的文件从项目排除,在生成的 MainViewModel.cs 编写之前的业务逻辑代码:
ViewModel\MainViewModel.cs :
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Windows;
namespace WPFDemo.ViewModel
{
public class MainViewModel : ViewModelBase
{
public RelayCommand<object> ShowInfoCommand { get; }
public string _name;
public string Name
{
get { return _name; }
set { _name = value; RaisePropertyChanged(); }
}
public string _description;
public string Description
{
get { return _description; }
set { _description = value; RaisePropertyChanged(); }
}
public MainViewModel()
{
Name = "菠萝吹雪";
Description = "哦,尊严,多少钱一斤哪。";
ShowInfoCommand = new RelayCommand<object>(ShowInfo);
}
public void ShowInfo(object parameter)
{
Name = parameter as string;
Description = parameter as string;
MessageBox.Show(parameter as string);
}
}
}
MainWindow.xaml :
<Window x:Class="WPFDemo.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:local="clr-namespace:WPFDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
DataContext="{Binding Main, Source={StaticResource Locator}}"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<Grid>
<StackPanel>
<TextBox Height="30" Text="{Binding Name}" />
<TextBox Height="30" Text="{Binding Description}" />
<TextBox x:Name="textBox"
Height="30"
Text="Hello,World!" />
<Button Command="{Binding ShowInfoCommand}"
CommandParameter="{Binding ElementName=textBox, Path=Text}"
Content="Click Me" />
</StackPanel>
</Grid>
</Window>
运行程序:
MVVM 工具包简介 。
CommunityToolkit.Mvvm 包(又名 MVVM 工具包,以前名为 Microsoft.Toolkit.Mvvm )是一个现代、快速且模块化的 MVVM 库.
💭没有 .Net Framework 的版本,本章终。。.
在 WPF 中,命令是一种用于处理用户交互操作的机制。它将操作行为与界面元素解耦,使得界面元素可以通过命令进行触发和执行相应的逻辑。 WPF 中的命令模型通过 ICommand 接口和相关的实现类来实现。命令模式的设计思想是将命令的发送者(例如按钮)与命令的执行者(例如视图模型中的方法)解耦,使得它们之间不直接依赖,提高代码的可维护性和重用性.
MVVM(Model-View-ViewModel) 是一种用于构建 WPF 应用程序的软件架构模式,它将应用程序的逻辑分为三个核心部分:模型、视图和视图模型。模型表示数据模型,负责数据的获取和处理;视图表示用户界面,负责界面的展示;视图模型是视图和模型之间的桥梁,负责处理业务逻辑、提供数据绑定和命令等功能。 MVVM 通过数据绑定和命令的方式实现视图和视图模型的通信,将界面逻辑和业务逻辑分离,使得代码更加清晰、可测试和可维护.
最后此篇关于WPF入门笔记-06-命令的文章就讲到这里了,如果你想了解更多关于WPF入门笔记-06-命令的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
有没有办法在另一个 WPF 窗口内托管 WPF 窗口。我有几个有点复杂的表格。但现在为了简化事情,我试图将其中一些合并为一个“仪表板”表单中的标签页。 请注意,我不是要托管 Windows 窗体,而是
WPF 特有的哪些方面和实践在非 WPF GUI 编程中最有用(并且并非难以实现)? 最佳答案 通过学习 WPF 命令,我了解了命令模式。它构成了 UI - 代码分离的基础,我认为应该在其他应用程序中
WinRT/Metro 正在获得一个新的 SemanticZoom控制,但我很难为 WPF 找到任何东西。 我不想为我的特定项目切换到 Metro,因为它不允许我制作窗口应用程序或跨多个显示器的多个实
我很难解决我的问题,我快要疯了。 想法是这样的:我有两个 ListView 元素,当一个元素从第一个列表掉落到第二个列表时,我需要打开一个对话,但我需要被掉落的元素的信息以及被添加以填充对话的元素。
如果我遵循TabControl,并且一切正常,当我切换到第二个Tabitem时,它显示就没有问题。 //datagrid //datagrid2 但是如果我有这个xaml,当我
在 Windows 窗体应用程序中,我们的数据 GridView 有很多事件,如行鼠标双击或行单击以及额外的...... 但是在 WPF 中我找不到这些事件。我如何将行鼠标双击添加到其中包含数据网格的
在这个项目中,代码 正确编译和执行 ;但是,我需要帮助解决两个问题: VS2012 WPF 设计器不适用于此 XAML 文件。它显示消息设计 View 对于 x64 和 ARM 目标平台不可用。 我收
目前我正在设计 WPF ScrollViewer,我发现了这个 Content="M 0 0 L 4 4 L 0 8 Z" 阅读 MSDN examples .现在我真的很想知道这意味着什么,但我无法
在 WPF 中,元素的可见性可以为“可见”,但实际上在屏幕上不可见,因为它的父元素(或父元素的父元素)具有折叠的可见性。 我希望能够知道一个元素是否实际呈现在屏幕上,而不必遍历可视化树检查父元素。 有
我应该使用 ApplicationCommands.Close用于关闭模式对话框还是该命令被认为是为关闭应用程序保留的?如果是后者,请大家创建Close每个命令 Dialog盒子或只是一个 Close
WPF 是否有任何可用的 piemenu 控件? 最佳答案 我在我的最爱中找到了这个,你可以看看: This 祝你今天过得愉快。 关于wpf - WPF 的菜单,我们在Stack Overflow上找
我正在尝试使用 WrapPanel 和两个 TextBlock 将星号 (*) 附加到某些文本的左侧,允许文本换行,并强制文本右对齐。通过创建一个 FlowDirection 设置为 RightToL
这里是场景(简化):我在Window上有一个控件(比如说一个Rectangle)。我迷上了MouseMove事件,以使其启动拖放操作。然后在MouseDown事件中进行动画处理,向右移动50个像素。但
我有一个 ListView ,它的项目来源是一个列表。我希望用户只选择一项。当我将 listview 的 SelectionMode 设置为 single 时,用户仍然可以选择多个项目,并且似乎 li
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
INotifyPropertyChanged 的目的是什么。我知道每当更改属性时都会触发此事件,但是 View /用户界面如何知道触发了此事件: 这是实现 INotifyPropertyChang
我正在查看工具箱中的 WPF 组件,但找不到 2005/2008 中存在的错误提供程序。 被移除了吗? 最佳答案 ErrorProvider是一个 Winforms 控件。 WPF 中没有等效项。但是
我试图在单击和双击 wpf Image 控件时有不同的行为。不幸的是,单击首先被触发,因此双击被忽略。 最佳答案 如果您改用 MouseDown 事件,则它在 EventArgs 中为 ClickCo
这可能吗? 我使用了一个框架控件并且:显示(例如:showwindow.xaml) 但是我得到这个错误: root element is not valid for navigation 最佳答案 确
我在蓝色背景的窗口上放置了一个扩展器,我想让扩展器的按钮与默认颜色不同(蓝色,它是从窗口接收的)。当我修改扩展器的背景属性时,它会将整个扩展器、标题和全部更改为新颜色。但是,我只想更改按钮本身。谁能指
我是一名优秀的程序员,十分优秀!