運行效果圖
程序集整體如下

<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>

<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>
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>
三個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 } }
<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!\n", "Log");//向Log發送消息 (追加文本) } } }

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!\n", "Log");//向Log發送消息 (追加文本) } } }