• WPF使用MVVMLight的ViewModel 访问控件的属性方法事件以及多页面传递信息


    运行效果图

     程序集整体如下

    <Window x:Class="MVVMLightDemo.View.MainView"
            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:MVVMLightDemo.View" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            mc:Ignorable="d"
            Title="MainView" Height="450" Width="800">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Column ="0">
                <Button Content="UI1" Command="{Binding UI1Command}" />
                <Button Content="UI2" Command="{Binding UI2Command}"/>
            </StackPanel>
            <GridSplitter Grid.Row="0" Grid.Column="1" Width="5" HorizontalAlignment="Left" VerticalAlignment="Stretch" Background="#FFC1BDC5" Grid.RowSpan="2" />
            <Grid Grid.Column="1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="100"/>
                </Grid.RowDefinitions>
                <GridSplitter Height="5" Grid.Row="0" Grid.Column="1" Background="#FFC1BDC5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"/>
                <Border  Grid.Row ="0"  BorderBrush="Gray" BorderThickness="1" >
                    <ContentPresenter  Content="{Binding Content}" Margin="5,0"/>
                    <!--使用内容呈现器来切换界面-->
                </Border>
    
                <Border Grid.Row ="1"  BorderBrush="Gray" BorderThickness="1">
                    <TextBox x:Name="LogTextBox" Text="{Binding TextLog}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" >
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Loaded">
                                <i:InvokeCommandAction Command="{Binding Path=TextBoxLoadedCommand}"
                                       CommandParameter="{Binding ElementName=LogTextBox}">
                                </i:InvokeCommandAction>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </TextBox>
                </Border>
            </Grid>
        </Grid>
    </Window>
    MainView.xaml

    <UserControl x:Class="MVVMLightDemo.View.UI1View"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:MVVMLightDemo.View"
                 mc:Ignorable="d" 
                 d:DesignHeight="100" d:DesignWidth="200">
        <Grid>
            <Button Content="UI1向日志界面传递信息" Command="{Binding BtnCommand}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Grid>
    </UserControl>
    UI1View.xaml

    UI1界面里只有一个Button并绑定一个命令,单击这个按键会向日志里打印文本,UI2和UI1类似

    <UserControl x:Class="MVVMLightDemo.View.UI2View"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:MVVMLightDemo.View"
                 mc:Ignorable="d" 
                 d:DesignHeight="100" d:DesignWidth="200">
        <Grid>
            <Button Content="UI2向日志界面传递信息" Command="{Binding BtnCommand}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
        </Grid>
    </UserControl>
    UI2View.xaml

    三个UI界面对应的三个ViewModel分别如下

    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.Command;
    using GalaSoft.MvvmLight.Messaging;
    using MVVMLightDemo.View;
    using System;
    using System.Windows.Controls;
    
    namespace MVVMLightDemo.ViewModel
    {
        /// <summary>
        /// This class contains properties that the main View can data bind to.
        /// <para>
        /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
        /// </para>
        /// <para>
        /// You can also use Blend to data bind with the tool's support.
        /// </para>
        /// <para>
        /// See http://www.galasoft.ch/mvvm
        /// </para>
        /// </summary>
        public class MainViewModel : ViewModelBase
        {
            /// <summary>
            /// Initializes a new instance of the MainViewModel class.
            /// </summary>
            /// 
            #region 成员
            TextBox TextBoxLog = new TextBox();
            public UserControl UserUI1 = new UI1View();
            public UserControl UserUI2 = new UI2View();
            #endregion
    
            #region 构造方法
            public MainViewModel()
            {
                ///Messenger:信使
                ///Recipient:收件人
                Messenger.Default.Register<string>(this, "Log", msg =>  //注册Log消息 其内容是向日志文本追加文本
                {
                    TextLog += msg;
                });
            }
            #endregion
    
            #region 绑定属性
            //主页面的内容呈现器
            private UserControl _content;
            public UserControl Content
            {
                get { return _content; }
                set { _content = value;RaisePropertyChanged(() => Content);}
            }
            //文本日志
            private string textlog;
            public string TextLog
            {
                get { return textlog; }
                set { textlog = value; RaisePropertyChanged(() => TextLog); }
            }
            #endregion
    
            #region Button UI1命令
            private RelayCommand ui1Command;
            public RelayCommand UI1Command
            {
                get
                {
                    if (ui1Command == null)
                        ui1Command = new RelayCommand(() => ExcuteUI1Command());
                    return ui1Command;
    
                }
                set { ui1Command = value; }
            }
    
            private void ExcuteUI1Command()
            {
                Content = UserUI1;
            }
            #endregion
    
            #region Button UI2命令
            private RelayCommand ui2Command;
            public RelayCommand UI2Command
            {
                get
                {
                    if (ui2Command == null)
                        ui2Command = new RelayCommand(() => ExcuteUI2Command());
                    return ui2Command;
    
                }
                set { ui2Command = value; }
            }
    
            private void ExcuteUI2Command()
            {
                Content = UserUI2;
            }
            #endregion
    
            #region TextBox 
            private RelayCommand<TextBox> textBoxLoadedCommand;
            public RelayCommand<TextBox> TextBoxLoadedCommand
            {
                get
                {
                    if (textBoxLoadedCommand == null)
                        textBoxLoadedCommand = new RelayCommand<TextBox>((p) => ExecuteTextBoxLoadedCommandCommand(p));
                    return textBoxLoadedCommand;
                }
                set { textBoxLoadedCommand = value; }
            }
    
            private void ExecuteTextBoxLoadedCommandCommand(TextBox p)
            {
                TextBoxLog = (System.Windows.Controls.TextBox)p;//TextBox加载的时候把自身最为参数传递到ViewModel里来,有了这个参数就可以在ViewModel中使用该控件的属性方法以及事件
                TextBoxLog.IsReadOnly = true;//设为只读(使用控件的属性)
                TextBoxLog.TextChanged += TextBoxLog_TextChanged;//添加文本发生改变的事件(使用控件的事件)
            }
    
            private void TextBoxLog_TextChanged(object sender, TextChangedEventArgs e)
            {
                TextBoxLog.ScrollToEnd();//文本发生改变的时候让文本自动滚到底部(使用控件的方法)
            }
            #endregion
        }
    }
    MainViewModel.cs
                    <TextBox x:Name="LogTextBox" Text="{Binding TextLog}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" >
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Loaded">
                                <i:InvokeCommandAction Command="{Binding Path=TextBoxLoadedCommand}"
                                       CommandParameter="{Binding ElementName=LogTextBox}">
                                </i:InvokeCommandAction>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </TextBox>

    在MainView.xaml中TextBox绑定了加载事件Loaded,这里绑定的事件命令的同时还传递了一个TextBox自身参数LogTextBox,这个参数会带到MainViewModel.cs文件中去

            private RelayCommand<TextBox> textBoxLoadedCommand;
            public RelayCommand<TextBox> TextBoxLoadedCommand
            {
                get
                {
                    if (textBoxLoadedCommand == null)
                        textBoxLoadedCommand = new RelayCommand<TextBox>((p) => ExecuteTextBoxLoadedCommandCommand(p));
                    return textBoxLoadedCommand;
                }
                set { textBoxLoadedCommand = value; }
            }
    
            private void ExecuteTextBoxLoadedCommandCommand(TextBox p)
            {
                TextBoxLog = (System.Windows.Controls.TextBox)p;//TextBox加载的时候把自身最为参数传递到ViewModel里来,有了这个参数就可以在ViewModel中使用该控件的属性方法以及事件
                TextBoxLog.IsReadOnly = true;//设为只读(使用控件的属性)
                TextBoxLog.TextChanged += TextBoxLog_TextChanged;//添加文本发生改变的事件(使用控件的事件)
            }
    
            private void TextBoxLog_TextChanged(object sender, TextChangedEventArgs e)
            {
                TextBoxLog.ScrollToEnd();//文本发生改变的时候让文本自动滚到底部(使用控件的方法)
            }

    在MainViewModel.cs中操作该参数就像在后台文件中操作MainView.xaml.cs中操作LogTextBox是一样的,有了这个参数就可以在MainViewModel.cs中任意位置使用该控件的属性和方法了,如果想使用控件的事件直接在加载命令中注册即可。

    在MainViewModel.cs构造方法中注册了一个信使名字叫做Log

            public MainViewModel()
            {
                ///Messenger:信使
                ///Recipient:收件人
                Messenger.Default.Register<string>(this, "Log", msg =>  //注册Log消息 其内容是向日志文本追加文本
                {
                    TextLog += msg;
                });
            }

    注册了这个信使后,就可以在其他页面的ViewModel中直接发送消息,发送的消息除了是string类型还可以是自定义类类型

    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.Command;
    using GalaSoft.MvvmLight.Messaging;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MVVMLightDemo.ViewModel
    {
        public class UI1ViewModel : ViewModelBase
        {
            private RelayCommand btnCommand;
            public RelayCommand BtnCommand
            {
                get
                {
                    if (btnCommand == null)
                        btnCommand = new RelayCommand(() => ExcuteBtnCommand());
                    return btnCommand;
    
                }
                set { btnCommand = value; }
            }
    
            private void ExcuteBtnCommand()
            {
                Messenger.Default.Send<string>("我是UI1!
    ", "Log");//向Log发送消息 (追加文本)
            }
        }
    }
    UI1ViewModel.cs
    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.Command;
    using GalaSoft.MvvmLight.Messaging;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MVVMLightDemo.ViewModel
    {
        public class UI2ViewModel : ViewModelBase
        {
            private RelayCommand btnCommand;
            public RelayCommand BtnCommand
            {
                get
                {
                    if (btnCommand == null)
                        btnCommand = new RelayCommand(() => ExcuteBtnCommand());
                    return btnCommand;
    
                }
                set { btnCommand = value; }
            }
    
            private void ExcuteBtnCommand()
            {
                Messenger.Default.Send<string>("我是UI2!
    ", "Log");//向Log发送消息 (追加文本)
            }
        }
    }
    UI2ViewModel.cs

     源码下载地址lizhiqiang0204/MVVMLightDemo (github.com)

  • 相关阅读:
    What is Continuous Integration?
    10 Essential TypeScript Tips And Tricks For Angular Devs
    javascript 的事件绑定和取消事件
    Directive Controller And Link Timing In AngularJS
    做事情的态度——做精做细
    How to simplify a PHP code with the help of the façade pattern?
    Can we say objects have attributes, states and behaviors?
    represent states with objects
    【转】一次是不算数的
    nyoj27-水池数目 (求连通块数目)【dfs】
  • 原文地址:https://www.cnblogs.com/lizhiqiang0204/p/14858786.html
Copyright © 2020-2023  润新知