[WPF] MVVM中实现不含Command属性的控件的Command绑定

原文:[WPF] MVVM中实现不含Command属性的控件的Command绑定

为建立中文知识库加块砖        ——中科大胡不归

0. 前言

虽然MVVM不推荐在ViewModel中操作View,但是实际情况可能是无法完全避免,当然也可能是作者段位不够。所以有了此文。
Button之类的按钮自身就有Command属性,可以*绑定代理方法。但是比如TextBlock没有Command属性,所以通过Interaction.Triggers来实现Command绑定。

本人的写作此文的背景只初学三个月的wpf的菜鸟级选手。

1. View代码

<Window x:Class="HelloMvvmLight.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:HelloMvvmLight"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <Binding Path="Main" Source="{StaticResource Locator}"></Binding>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Text="{Binding Title}" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter">
                    <i:InvokeCommandAction Command="{Binding SuccessCmd}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBlock>
        <Button Grid.Row="1" Command="{Binding ChangeTitleCommand}"></Button>
    </Grid>
</Window>

绑定的是TextBlock的MouseEnter(鼠标滑入)事件,绑定的方法名为SuccessCmd,传入的参数是Window类型的MainWindow。

2. ViewModel代码

public class MainViewModel : ViewModelBase
    {
        private string title;
        
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            Title = "Hello World";
        }

        public string Title
        {
            get { return title; }
            set { Set(ref title , value); }
        }

        public RelayCommand ChangeTitleCommand => new Lazy<RelayCommand>(
            () => new RelayCommand(ChangeTitle)
            ).Value;

        public RelayCommand<MainWindow> SuccessCmd => new Lazy<RelayCommand<MainWindow>>(() =>
            new RelayCommand<MainWindow>(OnTextChanged)
        ).Value;

        private void ChangeTitle()
        {
            Title = "Hello MvvmLight";
        }
        
        private static void OnTextChanged(MainWindow window)
        {
            window.Title = "我来自ViewModel";
            MessageBox.Show("xxxx");
        }
    }

SuccessCmd的实现是基于MvvmLight库的RelayCommand封装实现,初学请照抄。

3. 效果

当鼠标滑进TextBlock的范围,标题被改为"我来自ViewModel"。

[WPF] MVVM中实现不含Command属性的控件的Command绑定

参考文章:

  1. MVVM中轻松实现Command绑定(二)传递Command参数

[WPF] MVVM中实现不含Command属性的控件的Command绑定

上一篇:WPF动态加载(绑定)矢量图标


下一篇:WPF-支持异步操作的ObservableCollection-AsyncObservableCollection