WPF中, 如何将控件的触发事件绑定到ViewModel

C# WPF入门学习主线篇(十)—— DataGrid常见属性和事件 在《C# WPF入门学习主线篇(十)—— DataGrid常见属性和事件》这篇文章中,我们深入探讨了 WPF 中 `DataGrid` 控件的使用。 阅读详情
AI摘要

博客围绕DataGrid等控件带闪电符号的触发事件展开,探讨传统事件驱动及绑定ViewModel的实现方式。介绍了实现ViewModel绑定前端触发事件的写法,分析核心代码,还提及在有ItemSource的控件内找不到后台属性和命令时的解决办法及相关绑定示例。

在DataGrid 等控件中, 有很多这种带闪电符号的触发事件. 如果用传统的事件驱动, 则直接在后台中建立 一个private PropertyChanged(Sender s, EventAgars Args) 即可. 但是如果需要绑定到ViewModel的话? 应该怎么做?
在这里插入图片描述
带闪电符号的触发事件

实现viewModel绑定前端触发事件的写法:

        <DataGrid
            x:Name="myDataGrid"
            AlternationCount="2"
            AutoGenerateColumns="False"
            FontSize="24"
            ItemsSource="{Binding Students}"
            SelectedItem="{Binding SelectStudent}"
            SelectionMode="Extended">

            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding DataGridSelectedCommand}" CommandParameter="{Binding ElementName=myDataGrid, Path=SelectedItems}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <DataGrid.ColumnHeaderStyle>
                <Style TargetType="DataGridColumnHeader">
                    <Setter Property="BorderThickness" Value="0,0,0,3" />
                    <Setter Property="Cursor" Value="Hand" />
                    <Setter Property="FontWeight" Value="SemiBold" />
                    <Setter Property="HorizontalContentAlignment" Value="Center" />
                    <Setter Property="Margin" Value="0" />
                    <Setter Property="MinHeight" Value="25" />
                    <Setter Property="MinWidth" Value="0" />
                    <Setter Property="Background" Value="#2B2C31" />
                    <Setter Property="SnapsToDevicePixels" Value="True" />
                </Style>
            </DataGrid.ColumnHeaderStyle>
            <DataGrid.CellStyle>
                <Style TargetType="DataGridCell">
                    <Setter Property="HorizontalContentAlignment" Value="Center" />
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="DataGridCell">
                                <Grid Background="{TemplateBinding Background}">
                                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGrid.CellStyle>
            <DataGrid.Columns>
                <DataGridTextColumn
                    Width="*"
                    Binding="{Binding Id}"
                    Header="Id" />
                <DataGridTextColumn
                    Width="*"
                    Binding="{Binding Age}"
                    Header="年龄" />
                <DataGridTextColumn
                    Width="*"
                    Binding="{Binding Name}"
                    Header="姓名" />
                <DataGridTemplateColumn Header="操作">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock
                                    Margin="5"
                                    HorizontalAlignment="Right"
                                    VerticalAlignment="Center"
                                    Background="White"
                                    FontFamily="{StaticResource fontAwesome}"
                                    FontSize="24"
                                    Tag="修改"
                                    Text="&#xf14b;">
                                    <i:Interaction.Triggers>
                                        <i:EventTrigger EventName="MouseUp">
                                            <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.DataGridUpDateCommand}" CommandParameter="{Binding}" />
                                        </i:EventTrigger>
                                    </i:Interaction.Triggers>
                                    <TextBlock.Style>
                                        <Style TargetType="TextBlock">
                                            <Style.Triggers>
                                                <Trigger Property="IsMouseOver" Value="True">
                                                    <Setter Property="Cursor" Value="Hand" />
                                                    <Setter Property="Foreground" Value="Orange" />
                                                </Trigger>
                                                <Trigger Property="IsMouseOver" Value="False">
                                                    <Setter Property="Foreground" Value="Black" />
                                                </Trigger>
                                            </Style.Triggers>
                                        </Style>
                                    </TextBlock.Style>
                                </TextBlock>
                                <TextBlock
                                    Margin="5"
                                    HorizontalAlignment="Right"
                                    VerticalAlignment="Center"
                                    Background="White"
                                    FontFamily="{StaticResource fontAwesome}"
                                    Tag="删除"
                                    Text="&#xf056;">
                                    <i:Interaction.Triggers>
                                        <i:EventTrigger EventName="MouseUp">
                                            <i:InvokeCommandAction Command="{Binding DataContext.DataGridDeleteCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="{Binding}" />
                                        </i:EventTrigger>
                                    </i:Interaction.Triggers>
                                    <TextBlock.Style>
                                        <Style TargetType="TextBlock">
                                            <Style.Triggers>
                                                <Trigger Property="IsMouseOver" Value="True">
                                                    <Setter Property="Cursor" Value="Hand" />
                                                    <Setter Property="Foreground" Value="Red" />
                                                </Trigger>
                                                <Trigger Property="IsMouseOver" Value="False">
                                                    <Setter Property="Foreground" Value="Black" />
                                                </Trigger>
                                            </Style.Triggers>
                                        </Style>
                                    </TextBlock.Style>
                                </TextBlock>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>

                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

分析核心代码:

            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding DataGridSelectedCommand}" CommandParameter="{Binding ElementName=myDataGrid, Path=SelectedItems}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>

i的命名空间 : xmlns:i=“http://schemas.microsoft.com/xaml/behaviors”

使用触发器, 事件触发器, 将前端的触发事件写在EventName中 SelectionChanged. 然后把事件绑定到后台, 将多选的Student 以CommandParameter的形式传入后端

后端代码:

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MathNet.Numerics.Distributions;
using NavTest.Eneities;
using SqlSugar;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NavTest.ViewModels
{
    public partial class Page3ViewModel:ObservableObject
    {
        [ObservableProperty]
        private ObservableCollection<Student> students = new();

        public Page3ViewModel()
        {
            for (int i = 0; i < 15; i++)
            {
                Students.Add(
                    new()
                    {
                        Id = i + 1,
                        Name = $"StudentName{i}",
                        Age = $"{i}+10",
                        Description = $"str+{i}"
                    }
                );
            }
        }

        [RelayCommand]
        public void DataGridDelete(Student student)
        {

        }

        //[RelayCommand]

        //public void DataGridUpDate(Student student)
        //{

        //}

        public RelayCommand<Student> DataGridUpDateCommand => new RelayCommand<Student>((arg) =>
        {

        });

        [RelayCommand]
        public void DataGridSelected(IList<object> objs)
        {
            MyStudents = new();
            foreach (var item in objs)
            {
                if (item is Student stu)
                {
                    MyStudents.Add(stu);
                }
            }

            Student stu1 = SelectStudent;
        }

        [RelayCommand]
        public void ItemControlCmd(Student student)
        {

        }

        [ObservableProperty]
        private ObservableCollection<Student> myStudents = new ();
        [ObservableProperty]
        private Student selectStudent = new();
    }
}

完整的前端代码:

<UserControl
    x:Class="NavTest.Views.Page3"
    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:hc="https://handyorg.github.io/handycontrol"
    xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
    xmlns:local="clr-namespace:NavTest.Views"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:mv="clr-namespace:NavTest.ViewModels"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:tt="clr-namespace:NavTest.Eneities"
    xmlns:vc="clr-namespace:NavTest.Components"
    d:DataContext="{d:DesignInstance mv:Page3ViewModel}"
    d:DesignHeight="450"
    d:DesignWidth="800"
    FontSize="24"
    mc:Ignorable="d">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <DataGrid
            x:Name="myDataGrid"
            AlternationCount="2"
            AutoGenerateColumns="False"
            FontSize="24"
            ItemsSource="{Binding Students}"
            SelectedItem="{Binding SelectStudent}"
            SelectionMode="Extended">

            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding DataGridSelectedCommand}" CommandParameter="{Binding ElementName=myDataGrid, Path=SelectedItems}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <DataGrid.ColumnHeaderStyle>
                <Style TargetType="DataGridColumnHeader">
                    <Setter Property="BorderThickness" Value="0,0,0,3" />
                    <Setter Property="Cursor" Value="Hand" />
                    <Setter Property="FontWeight" Value="SemiBold" />
                    <Setter Property="HorizontalContentAlignment" Value="Center" />
                    <Setter Property="Margin" Value="0" />
                    <Setter Property="MinHeight" Value="25" />
                    <Setter Property="MinWidth" Value="0" />
                    <Setter Property="Background" Value="#2B2C31" />
                    <Setter Property="SnapsToDevicePixels" Value="True" />
                </Style>
            </DataGrid.ColumnHeaderStyle>
            <DataGrid.CellStyle>
                <Style TargetType="DataGridCell">
                    <Setter Property="HorizontalContentAlignment" Value="Center" />
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="DataGridCell">
                                <Grid Background="{TemplateBinding Background}">
                                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGrid.CellStyle>
            <DataGrid.Columns>
                <DataGridTextColumn
                    Width="*"
                    Binding="{Binding Id}"
                    Header="Id" />
                <DataGridTextColumn
                    Width="*"
                    Binding="{Binding Age}"
                    Header="年龄" />
                <DataGridTextColumn
                    Width="*"
                    Binding="{Binding Name}"
                    Header="姓名" />
                <DataGridTemplateColumn Header="操作">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock
                                    Margin="5"
                                    HorizontalAlignment="Right"
                                    VerticalAlignment="Center"
                                    Background="White"
                                    FontFamily="{StaticResource fontAwesome}"
                                    FontSize="24"
                                    Tag="修改"
                                    Text="&#xf14b;">
                                    <i:Interaction.Triggers>
                                        <i:EventTrigger EventName="MouseUp">
                                            <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.DataGridUpDateCommand}" CommandParameter="{Binding}" />
                                        </i:EventTrigger>
                                    </i:Interaction.Triggers>
                                    <TextBlock.Style>
                                        <Style TargetType="TextBlock">
                                            <Style.Triggers>
                                                <Trigger Property="IsMouseOver" Value="True">
                                                    <Setter Property="Cursor" Value="Hand" />
                                                    <Setter Property="Foreground" Value="Orange" />
                                                </Trigger>
                                                <Trigger Property="IsMouseOver" Value="False">
                                                    <Setter Property="Foreground" Value="Black" />
                                                </Trigger>
                                            </Style.Triggers>
                                        </Style>
                                    </TextBlock.Style>
                                </TextBlock>
                                <TextBlock
                                    Margin="5"
                                    HorizontalAlignment="Right"
                                    VerticalAlignment="Center"
                                    Background="White"
                                    FontFamily="{StaticResource fontAwesome}"
                                    Tag="删除"
                                    Text="&#xf056;">
                                    <i:Interaction.Triggers>
                                        <i:EventTrigger EventName="MouseUp">
                                            <i:InvokeCommandAction Command="{Binding DataContext.DataGridDeleteCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="{Binding}" />
                                        </i:EventTrigger>
                                    </i:Interaction.Triggers>
                                    <TextBlock.Style>
                                        <Style TargetType="TextBlock">
                                            <Style.Triggers>
                                                <Trigger Property="IsMouseOver" Value="True">
                                                    <Setter Property="Cursor" Value="Hand" />
                                                    <Setter Property="Foreground" Value="Red" />
                                                </Trigger>
                                                <Trigger Property="IsMouseOver" Value="False">
                                                    <Setter Property="Foreground" Value="Black" />
                                                </Trigger>
                                            </Style.Triggers>
                                        </Style>
                                    </TextBlock.Style>
                                </TextBlock>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>

                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

        <WrapPanel
            Grid.Row="1"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Orientation="Horizontal">
            <TextBlock
                Margin="5,5,5,5"
                Foreground="White"
                Text="测试1" />
            <TextBlock
                Margin="5,5,5,5"
                Foreground="White"
                Text="测试2" />
            <TextBlock
                Margin="5,5,5,5"
                Foreground="White"
                Text="测试3" />
            <TextBlock
                Margin="5,5,5,5"
                Foreground="White"
                Text="测试4" />
            <TextBlock
                Margin="5,5,5,5"
                Foreground="White"
                Text="测试5" />
            <TextBlock
                Margin="5,5,5,5"
                Foreground="White"
                Text="测试6" />
        </WrapPanel>

        <Grid Grid.Row="1" Grid.Column="1">
            <ItemsControl AlternationCount="2" ItemsSource="{Binding MyStudents}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Border x:Name="border" Padding="2">
                            <StackPanel>
                                <TextBlock Foreground="White" Text="{Binding Name}" />
                                <TextBlock Foreground="White" Text="{Binding Age}" />
                                <Button
                                    Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.ItemControlCmdCommand}"
                                    CommandParameter="{Binding}"
                                    Content="{Binding Description}"
                                    Foreground="White" />
                            </StackPanel>
                        </Border>
                        <DataTemplate.Triggers>
                            <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                                <Setter TargetName="border" Property="Background" Value="red" />
                            </Trigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Grid>
    </Grid>
</UserControl>


如果在一个有ItemSource的控件内找不到 后台的Property 和command, 可以尝试 binding ElementName 和binding Relationsource

例如command 可以 binding Relationsource = {RelationSource AncestorType = window} path = datacontext. xxxcommand
commandparameter={binding} 返回单个class为数据源

CommandParameter=“{Binding ElementName=myDataGrid, Path=SelectedItems}” 绑定别的控件上的属性 或者 用child的方式

一些补充的内容:

除了BooleanToVisibilityConverter之外,WPF框架还提供了许多其他的内置转换器。以下是一些常用的系统现有转换器的示例:

BooleanToVisibilityConverter: 将bool值转换为Visibility枚举值。
InverseBooleanConverter: 反转bool值,将true转换为false,将false转换为true。
StringFormatConverter: 格式化字符串,可以将值与指定的格式字符串进行组合。
DateTimeConverter: 将DateTime对象转换为不同格式的字符串,或者将字符串转换为DateTime对象。
BrushConverter: 将字符串表示的颜色转换为Brush对象。
ValueConverterGroup: 将多个转换器组合成一个组,按照顺序依次进行转换。
EnumToStringConverter: 将枚举值转换为对应的字符串表示。
NumericUpDownConverter: 用于增加和减少数值类型的转换器。
CollectionViewSource: 用于在集合和视图之间进行转换和筛选。
这只是一些常见的示例,WPF框架提供了更多的内置转换器,可以满足各种转换需求。你可以根据具体的场景和需求选择合适的转换器来使用。

eventTrriger
DataTrigger

常用触发器:

CallMethodAction
ChangePropertyAction
InvokeCommandAction


CallMethodAction 和 InvokeCommandAction 是在 WPF 中用于触发操作的两种不同方式,它们有一些区别,并且在特定的情况下可能不可互相替代。

CallMethodAction:CallMethodAction 允许你直接调用指定的方法。你可以通过设置 TargetObject 属性指定要调用方法的对象,并使用 MethodName 属性指定要调用的方法名称。这种方式适用于简单的、特定于 UI 的操作,例如在按钮点击或其他事件发生时执行某个方法。它可以方便地将事件触发与方法调用关联起来,但缺点是它与 UI 逻辑紧耦合,并且无法利用 WPF 中的命令系统。

InvokeCommandAction:InvokeCommandAction 允许你通过绑定一个命令来执行操作。你可以使用 Command 属性绑定到一个实现了 ICommand 接口的命令对象。当触发与行为关联的事件时,命令的 Execute 方法将被调用,而命令的 CanExecute 方法决定是否可以执行。这种方式更符合 MVVM 架构和解耦原则,它将 UI 逻辑与业务逻辑分离,并提供了更好的可测试性和可重用性。

虽然 CallMethodAction 和 InvokeCommandAction 实现了类似的功能,但在大多数情况下,推荐使用 InvokeCommandAction 和命令模式来处理用户交互。它更符合 MVVM 设计模式的理念,并且提供了更好的灵活性和可扩展性。但在一些简单的场景下,CallMethodAction 也可以作为一种快速临时解决方案。

因此,根据具体的需求和架构设计,你可以选择使用 CallMethodAction 或 InvokeCommandAction 来触发操作。


在 WPF 中,CallMethodAction 是一种交互行为(Interaction Behavior),它允许你通过 XAML 触发调用特定方法。它是 System.Windows.Interactivity 命名空间下的一个类,需要通过添加对 System.Windows.Interactivity 程序集的引用才能使用。

CallMethodAction 可以用于任何具有无参数的方法。它与事件触发器(EventTrigger)一起使用,当特定事件发生时,将触发并调用绑定的方法。

以下是使用 CallMethodAction 的示例:

CallMethodAction :===============


<StackPanel>
    <Button Content="Click Me">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
                <i:CallMethodAction TargetObject="{Binding}" MethodName="HandleButtonClick" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>
</StackPanel>

关闭窗口,用到window的close方法:
                <Button
                    Background="Red"
                    Content="&#xe653;"
                    Style="{StaticResource ControlButtonStyle}"
                    ToolTip="Close">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Click">
                            <i:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Button>



ChangePropertyAction=============
例如:TargetObject="{Binding} 返回了DataContext,就是ViewModel,它的PropertyName就是里面的属性IsMarker

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:ChangePropertyAction PropertyName="IsMarker" Value="True" TargetObject="{Binding}"/>
        </i:EventTrigger>
        <i:EventTrigger EventName="Closing">
            <i:ChangePropertyAction PropertyName="IsMarker" Value="False" TargetObject="{Binding}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

最小化,用到window的Minimized属性:

                <Button
                    Background="#22FFFFFF"
                    Content="&#xe7e6;"
                    Style="{StaticResource ControlButtonStyle}"
                    ToolTip="Minimize">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Click">
                            <i:ChangePropertyAction
                                PropertyName="WindowState"
                                TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}"
                                Value="Minimized" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Button>



<Button Content="Change Background">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <i:ChangePropertyAction TargetObject="{Binding ElementName=MyBorder}"
                                    PropertyName="Background"
                                    Value="Red" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>
<Border x:Name="MyBorder" Width="100" Height="100" Background="Green" />



<Button Content="Change Background">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <i:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
                                    PropertyName="Background"
                                    Value="Red" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

=============

                        <RadioButton
                            Width="200"
                            Height="50"
                            Content="连接PLC"
                            FontSize="18"
                            Foreground="White"
                            Style="{DynamicResource RadioButtonMenuStyle}"
                            Tag="&#xf11c;">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Checked">
                                    <i:InvokeCommandAction Command="{Binding ConnCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=RadioButton}}" />
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </RadioButton>


============


在 <i:EventTrigger> 元素中,可以使用不同的 EventName 属性来指定常见事件的名称,以触发相应的动作或触发器。以下是一些常用的 EventName 值示例:

Loaded:当元素加载完成时触发。
Unloaded:当元素卸载时触发。
MouseEnter:当鼠标指针进入元素时触发。
MouseLeave:当鼠标指针离开元素时触发。
MouseDown:当鼠标按下按钮时触发。
MouseUp:当鼠标释放按钮时触发。
Click:当元素被点击时触发。
Checked:当复选框或单选按钮的选中状态改变时触发。
TextChanged:当文本框的文本内容改变时触发。
PreviewMouseMove:鼠标在元素上移动。
PreviewMouseUp:鼠标释放按钮。
MouseEnter:鼠标进入元素。
MouseLeave:鼠标离开元素。
PreviewMouseWheel:滚动鼠标滚轮。
键盘事件:

PreviewKeyDown:按下键盘上的键。
PreviewKeyUp:释放键盘上的键。
KeyDown:按下键盘上的键(冒泡事件)。
KeyUp:释放键盘上的键(冒泡事件)。


SelectionChanged:当下拉列表、列表框或其他选择控件的选择项发生改变时触发。
这只是一些常见的 EventName 值示例,实际上,可以根据具体的控件和需求,选择适合的事件名称。根据控件的类型和事件的定义,可以在相关文档或控件的事件文档中找到更多可用的 EventName 值。


<Button Content="Toggle Size" Width="100" Height="30">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <i:Interaction.Behaviors>
                <ei:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}"
                                         PropertyName="WindowState">
                    <ei:ChangePropertyAction.Value>
                        <System:WindowState>
                            <System:WindowState x:FactoryMethod="FromValue">
                                <System:WindowState.Normal />
                                <System:WindowState.Maximized />
                            </System:WindowState>
                        </System:WindowState>
                    </ei:ChangePropertyAction.Value>
                </ei:ChangePropertyAction>
            </i:Interaction.Behaviors>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>



========i:DataTrigger========

{Binding RelativeSource  = {RelativeSource Self} 
{Binding RelativeSource = {RelativeSource  AncestorType=Button}}  

{Binding ElementName=TestTBlock, Path=Name}


<Button Content="Click Me">
    <i:Interaction.Triggers>
        <i:DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path = IsMouseOver}" Value="False">
            <i:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource Self}}"
                                    PropertyName="BackGround"
                                    Value="Red" />
        </i:DataTrigger>
    </i:Interaction.Triggers>
</Button>

wpf dataGrid 实现单行某个数据变化 ui 界面随之响应 背景介绍:一行数据 比如 有 姓名 年龄 id 号 当 id 变化 更新 id 当 年龄变化 更新年龄 以 id 作为编号 如果 id 变化了则新增 否则更改 2 封装 model 类 3 封装 接口类 ITest 4 定义子类 5 定义 viewModel 类 6 xaml...... 阅读详情

相关推荐

WPF Mvvm模式下面如何将事件映射到ViewModel层

平常用惯了Command绑定,都快忘记传统的基于事件编程模式了,但是Commond模式里面有个明显的问题,就是你无法获取到事件源的参数。很多大聪明肯定会说,这还不简单,通过自己写控件,给控件加个自定义属性不就行了,想要啥事件就写啥事件进去,完全自主可控。但是对于写控件这种事情来说大部分人都还是比较吃力的,及时能写,你能保证你写的没有bug,后期使用不会引入别的问题。其实这一块WPF底层早都已经考虑到了并封装好了常用的Behaviors,只是好多人还不了解咋使用罢了。

星火燎猿 2219

WPF MVVM基础教程(三)命令/事件的绑定

wpf中关于按钮Button、菜单项MenuItem等关于点击交互的事件,可以通过命令Command在ViewModel 中实现。将控件属性或者控件本,当做参数传入在CommandParameter中绑定ElementName对应控件的name,和属性名称。 除了点击事件通过Command绑定之外,想要绑定其他命令如MouseEnter、SelectionChanged等事件,则需要导入专门的nuget包,安装System.Windows.Interactivity.WPF包

海盗Sharp的博客 1万+

WPF Prism MVVM动态控件拖放缩放旋转实现指南

在WPF中实现可交互的动态控件(如矩形、图片)涉及坐标系建模、渲染变换与用户输入协同等基础图形学原理。核心在于理解Canvas绝对坐标、RenderTransform视觉变换及鼠标事件坐标的三层映射关系,避免因坐标未对齐导致拖动错位、缩放偏移或旋转失焦。通过CompositeTransform(实际采用TransformGroup)统一管理平移、缩放、旋转的正交变换,并以控件中心为锚点确保行为符合用户直觉;结合Prism的Region管理和MVVM状态绑定,使每个控件拥有独立可序列化、可撤销的Transfo

weixin_33824385的博客 253

WPF MVVM基础教程(二)各种基础的绑定

MVVM各种基础的绑定:视图View跟ViewModel绑定,将ViewModel对象赋值给DataContext;普通属性绑定;集合绑定ItemsSource,数量不变和数量变化ObservableCollection

海盗Sharp的博客 4369

【机器人】转动的指数坐标表示心得理解

转动的指数坐标表示心得理解1.前言2.指数坐标表示旋转矩阵3.原理推导4.矩阵对数、矩阵指数 1.前言 最近因为项目需求,又学习了一点机器人学的东西,参考书籍为《现代机器人学》,该书采用指数坐标、旋量的方式来对机器人进行描述和运动学、动力学建模,让我对机器人有了更深的理解,也是弥补DH参数建模复杂的缺陷,虽然DH法只用4个参数,而旋量需要更多,但是它骚啊! 本文是我学习了转动的指数坐标表示的一个心得体会,如有问题请多多包涵。 2.指数坐标表示旋转矩阵 指数坐标可以用来表示求解旋转矩阵,其原理非常简单巧妙,需

要恰饭得嘛 2328

脑电分析中的频谱特征提取 —— 从理论到实践

本文系统介绍了脑电信号(EEG)频谱特征提取方法及其应用。EEG信号通过频谱分析可分为Delta、Theta、Alpha、Beta和Gamma等具有明确生理意义的频段。文章详细讲解了功率谱密度、频带功率、相对功率、频谱熵等关键特征的计算方法,并提供了Python实现示例,包括模拟数据和真实CHB-MIT癫痫数据集的处理流程。这些频谱特征在脑机接口、情绪识别、疲劳监测和癫痫检测等领域具有重要应用价值。文章强调频谱特征结合时域和非线性特征可提升分析效果,为EEG研究提供了实用指导。

qq_32516809的博客 1441

view和viewmodel交互的几种方式

如果使用command必须要新建一个类实现command接口,然后在viewmodel里使用这个类定义command属性,这个在网上有大量案例所以就不说多少了。第三种,意外情况,使用代理类(当在viewmodel批量生成控件时候(前台必须有控件模板))第一种,使用caliburn.micro框架,可能导致控件的事件无法正常绑定所以有了这个方法。viewmodel页的关联代码是。

weixin_38157505的博客 809

SAP ABAP 如何实现物料主数据接口的增量传输机制?

如何实现物料主数据接口的增量传输机制?我在各客户系统中看到了五花八门的实现方式,即使是 IBM 实施的开发质量也并没有保证。其实这是一个很简单的问题,下面以物料主数据接口为例子,介绍 SAP 中更改文档对象的接口数据增量传输机制。

SAP李斌,本人承诺所有原创文章均不使用任何AI生成技术,请大家放心阅读。 1316

WPF的MVVM框架对于没有控件不存在Command属性如何调用RelayCommand类

set;set;// 执行按钮1的命令// 执行按钮2的命令。

meng2561199694的博客 588

基于AI的智能开发环境—Trae在Web开发中的应用实战与性能评估【Trae项目实战】

Trae 是一款与 AI 深度集成的开发工具,提供智能问答、代码自动补全和基于 Agent 的 AI 自动编程能力,极大提升开发效率。它具备完备的 IDE 功能,如代码编写、项目管理和源代码管理等,同时还具备强大的 AI 助手,能够提供智能问答、实时代码建议、代码片段生成等服务。开发者可以通过自然语言与 AI 协作,从 0 到 1 开发项目,AI 会根据需求自动生成代码或创建文件。

一键难忘的博客 3万+

NR PUCCH(二)PUCCH format 2/3/4

继续看PUCCH2/3/4:PUCCH format 0和1所携带的信息bits少,UCI bits2bits,信息bit需要经过编码等过程下面分别来看。

ModemProtocol的博客 538

WPF——事件绑定命令

我们都知道WPF中的命令在结合MVVM模式的框架使用之后(框架重新实现了ICommand),可以解耦。但并不是所有控件都可以绑定命令的,比如TextBox、ComboBox等。在使用这类控件时,如果你想让它的某个事件激发时调用ViewModel中的方法,往往需要把ViewModel中的方法暴露给View,然后在事件处理器中调用。这种调用方式增加了耦合度,虽然从短期实现来讲也没啥问题,但会让强迫症患者非常难受。目前收集了两种解决方法:这使UIElement类自带的一个属性, 你可以给它添加鼠标按键绑定和键盘

三千幻想乡 5077

【YOLO26保姆级零踩坑教程】环境搭建+五大任务快速入门,一行代码实现检测/分割/姿态/OBB/分类(Win+Linux全适配)

YOLO26环境搭建与实战指南:零踩坑全适配 本文是YOLO26全栈技术专栏的入门篇,提供Windows/Linux双系统的纯实战环境搭建指南,主打零踩坑、全适配。YOLO26基于Ultralytics框架优化,无需编译源码或手动下载权重,原生支持多任务推理。 环境配置关键点: 必须安装Ultralytics 8.4.0及以上版本 支持CPU/GPU环境,推荐Python 3.8-3.11 提供清华源配置解决下载慢问题 安装步骤: CPU版:一键安装Ultralytics和OpenCV GPU版:匹配CUD

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 774

WPF 任意事件绑定

WPF任意事件的绑定

qq_26062333的博客 1600

【温室气体】GOSAT 数据产品

【温室气体】GOSAT 数据产品

WW、forever的博客 238

5套高颜值AI漫剧女主设定图!直接拿去做漫剧(附完整提示词)

左侧特写放大表现暖棕眼妆、豆沙唇、红宝石首饰、发丝与针织纹理,四个视图严格保持同一人物脸模、发色、服装、首饰和身体比例,柔和复古棚拍光,低饱和酒红与奶油色配色,真实布料、皮革、金属与宝石材质,高级精致角色资产设定图,高清8K。佩戴珍珠与透明水晶耳坠、纤细珍珠项链;左侧特写放大至胸部以上,清晰表现皮肤、眼妆、发丝、耳饰和针织材质,人物四个视图保持同一脸模、发型、服装、饰品和身体比例,柔和棚拍漫射光,轻微地面阴影,高级细腻材质,真实发丝,细腻皮肤,高精度角色资产设定图,高清8K质感。

欢迎来到鸾姝淡月博客,专为程序员和编程爱好者打造的技术博客。我们分享编程语言趋势、开发工具、编程哲学、职业发展等,助你掌握新技术,优化技能,激发编程热情。 1686

WPF事件绑定到vm方法

方法1 第一步,在前端引入命名空间 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 第二步,前端事件绑定vm中的命令 <Window x:Class="Wp.WpfDemo.UIL.Views.Windows.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xml

wu_pan123的博客 1455

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

VUE于WPF中MvvM模式异同

因为在学VUE和WPF,又由于它们都采用了Mvvm模式,所以这里做一个简单的对比记录,方便记忆 1.Vue意义上的ViewModel和View通常在一个页面,通过new Vue创建ViewModel,el指定页面View中的id并关联起来,data提供json数据以供绑定,methods提供函数以供绑定。代码如下: <body> <div id="vue_det">...

u014650759的专栏 3770

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

WPF中MVVM模式下控件自有的事件绑定

1、原因 在WPF中单纯的命令绑定往往不能满足覆盖所有的事件,例如ComboBox的SelectionChanged事件,DataGrid的SelectionChanged事件等等,这时就可以用事件绑定来完成。 2、示例 事件绑定需要用到:System.Windows. interactivity.dll 库,如果安装了Blend for visual studio,里面就包含了这...

weixin_30764137的博客 786

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

整理:WPF用于绑定命令和触发路由事件的自定义控件写法

目的:自定义一个控件,当点击按钮是触发到ViewModel(业务逻辑部分)和Xaml路由事件(页面逻辑部分)   自定义控件增加ICommand #region - 用于绑定ViewModel部分 - public ICommand Command { get { return (ICommand)GetValue(...

HeBianGu的博客 6740

基于WPF系统框架设计(7)-TextBox/PasswordBox在ViewModel中支持回车命令

应用场景 我现在做一个系统登录功能,要求在PasswordBox上输完密码后回车,能够响应Enter事件,并执行ViewModel中对应的方法。如果登录成功则隐藏当前窗口显示主窗体,登录失败则焦点返回到用户名TextBox中,并全选文字,方便用户再重新输入。 这个在我们制造业自动化流程控制中,做防呆功能是很明显的,因为没有人为去参与。 如果像Winform一样的开发模式,就相对很简单了,现在...

weixin_30835649的博客 481

WPF —— MVVM架构

MVVM是一种软件架构模式,它将应用程序分为三个层次 model(数据模型),view(视图),viewmodel(视图模型)model:表示应用程序当中数据和业务逻辑,通俗来说就是对象。例如学生的姓名和年龄等放到一个class里面,作为一个对象view:就是xaml文件,处理用户交互和展示数据的 交互就是事件click,展示就是数据绑定等viewmodel:数据和页面之间的桥梁,可以处理一些ui逻辑,也可以处理数据绑定,可以执行ui界面的命令(类似于事件)也可以处理ui界面事件。

一个新人博客,愿多多支持。 7491

【wpf】WPF 中的 MouseBinding 详解

这篇文章详细介绍了WPF中的MouseBinding功能及其在MVVM模式下的应用。主要内容包括:1) MouseBinding的定义,它可将鼠标手势与命令直接绑定;2) 常用MouseGesture配置,包括各种鼠标按键与修饰键组合;3) MouseBinding的使用位置,如控件、窗口或DataTemplate中;4) 通过ItemsControl示例展示了如何为列表项添加双击命令;5) 使用要点和常见问题解答。文章强调MouseBinding能简化事件处理逻辑,特别适合MVVM开发模式。

songhuangong123的博客 1052

MVVM设计模式和在WPF中的实现(四) 事件绑定

系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中的实现(三)命令绑定 MVVM模式解析和在WPF中的实现(四)事件绑定 MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信 MVVM模式解析和在WPF中的实现(六)用依赖注入的方式配置ViewModel并注册消息 ...

weixin_30675967的博客 134
上一篇: 2分钟讲清楚C#的委托, C语言的函数指针,Java的函数式接口
下一篇: .netCore用DispatchProxy实现动态代理
潘诺西亚的火山
博客等级 码龄10年 7415粉丝 283原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值