<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.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">
<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">
<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
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
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
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
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
if (btnCommand == null)
btnCommand = new RelayCommand(() => ExcuteBtnCommand());
return btnCommand;
set { btnCommand = value; }
private void ExcuteBtnCommand()
Messenger.Default.Send<string>("我是UI1!\n", "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
if (btnCommand == null)
btnCommand = new RelayCommand(() => ExcuteBtnCommand());
return btnCommand;
set { btnCommand = value; }
private void ExcuteBtnCommand()
Messenger.Default.Send<string>("我是UI2!\n", "Log");//向Log发送消息 (追加文本)
UI2ViewModel.cs
源码下载地址lizhiqiang0204/MVVMLightDemo (github.com)