【1.7 MVVM:数据绑定、命令绑定】WPF案例代码解析
此案例演示 WPF 中 MVVM 模式的数据绑定、命令绑定
- 字符串绑定
- 数值绑定
- 控件属性绑定
- RadioButton 的枚举绑定
- 转换器
- DataGrid 数据绑定
- 命令绑定
2021-08-15 修改
添加 listbox、ListView、TreeView、menu 数据绑定
项目链接,enjoy
NuGet 下载 MvvmLightLibs,没有问题

xaml 文件引用
xmlns:core="clr-namespace:System;assembly=mscorlib"
xmlns:model="clr-namespace:MvvmCmdBinding.Model"
xmlns:converter="clr-namespace:MvvmCmdBinding.Converter"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:cmd="http://www.galasoft.ch/mvvmlight"
xmlns:viewmodel="clr-namespace:MvvmCmdBinding.ViewModel"
Name="MVVMWindow"
资源:枚举和转换器
<Window.Resources>
<ObjectDataProvider x:Key="DemoGender" MethodName="GetValues" ObjectType="{x:Type core:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type Type="model:Gender"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<converter:BoolToVisibilityConverter
x:Key="BoolToVisibility"/>
<converter:EnumToBoolConverter x:Key="EnumToBool"/>
</Window.Resources>
命令绑定
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<cmd:EventToCommand Command="{Binding CmdLoaded}" CommandParameter="{Binding ElementName=MVVMWindow}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<cmd:EventToCommand Command="{Binding CmdMouseMove}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseDown">
<cmd:EventToCommand Command="{Binding CmdMouseDown}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
DataContext
<Window.DataContext>
<viewmodel:ViewModelMain/>
</Window.DataContext>
界面

<UniformGrid Rows="1" Columns="2">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="3">
<Label Content="Binding Text" Width="120"/>
<TextBox Text="{Binding BindingText}" MinWidth="100" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="3">
<Label Content="Binding Number" Width="120"/>
<TextBox x:Name="TextValue" Text="{Binding BindingNumber, StringFormat={}{0:F3}}" MinWidth="100" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="3">
<Label Content="Binding Control" Width="120"/>
<TextBox Text="{Binding ElementName=TextValue, Path=Text}" MinWidth="100" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="3">
<Label Content="Binding Enum" VerticalAlignment="Center" Width="120"/>
<StackPanel Margin="3">
<RadioButton Content="Male" IsChecked="{Binding BindingEnum, Mode=TwoWay, Converter={StaticResource EnumToBool}, ConverterParameter=0}" Margin="3"/>
<RadioButton Content="Female" IsChecked="{Binding BindingEnum, Mode=TwoWay, Converter={StaticResource EnumToBool}, ConverterParameter=1}" Margin="3"/>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="3">
<Label Content="Binding Converter" Width="120"/>
<Label Content="IsVisible" VerticalAlignment="Center" Visibility="{Binding ElementName=CheckBoxControl, Path=IsChecked, Converter={StaticResource BoolToVisibility}}"/>
<CheckBox Name="CheckBoxControl" IsChecked="True" Content="Controller" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="3">
<Label Content="Mouse Position" Width="120"/>
<Label Content="{Binding ShowingText}" VerticalAlignment="Center"/>
</StackPanel>
</StackPanel>
<StackPanel Margin="3">
<DataGrid ItemsSource="{Binding DataList}" AutoGenerateColumns="False" Margin="3">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Number}" Header="Number" Width="*"/>
<DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="*"/>
<DataGridComboBoxColumn ItemsSource="{Binding Source={StaticResource DemoGender}}" SelectedValueBinding="{Binding Type}" Header="Gender" Width="*"/>
<DataGridCheckBoxColumn Binding="{Binding IsChecked}" Header="IsChecked" Width="*"/>
</DataGrid.Columns>
</DataGrid>
<StackPanel Orientation="Horizontal">
<Button Content="Cmd without parameter" Margin="3" Command="{Binding CmdWithoutParameter}"/>
<Button Content="Cmd with parameter" Margin="3" Command="{Binding CmdWithParameter}" CommandParameter="CommandParameter"/>
</StackPanel>
</StackPanel>
</UniformGrid>
ViewModelMain.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using MvvmCmdBinding.Model;
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
namespace MvvmCmdBinding.ViewModel
/// ----------------------------------------------------------------
/// Author : Taosy.W
/// Created Time: 2021/8/6 23:59:18
/// Description :
/// ------------------------------------------------------
/// Version Modified Time Modified By Modified Content
/// V1.0.0.0 2021/8/6 23:59:18 Taosy.W
public class ViewModelMain : ViewModelBase
private string bindingText;
public string BindingText
get => bindingText;
set =>
Set(ref bindingText, value);
private double bindingNumber;
public double BindingNumber
get => bindingNumber;
set => Set(ref bindingNumber, value);
private Gender bindingEnum;
public Gender BindingEnum
get => bindingEnum;
set => Set(ref bindingEnum, value);
private string showingText;
public string ShowingText
get => showingText;
set => Set(ref showingText, value);
private ObservableCollection<DataModel> dataList;
public ObservableCollection<DataModel> DataList
get => dataList;
set => Set(ref dataList, value);
public RelayCommand<MainWindow> CmdLoaded => new Lazy<RelayCommand<MainWindow>>(() => new RelayCommand<MainWindow>(Loaded)).Value;
private void Loaded(MainWindow window)
MessageBox.Show("MainWindow Loaded: " + window.ActualWidth + " * " + window.ActualHeight);
public RelayCommand<MouseEventArgs> CmdMouseMove => new RelayCommand<MouseEventArgs>(MouseMove);
private void MouseMove(MouseEventArgs e)
// 显示鼠标所在位置
System.Windows.Point point = e.GetPosition(e.Device.Target);
ShowingText = point.X + ", " + point.Y;
public RelayCommand CmdWithoutParameter => new Lazy<RelayCommand>(() => new RelayCommand(WithoutParameter)).Value;
private void WithoutParameter()
MessageBox.Show("Command Binding without parameter");
public RelayCommand<string> CmdWithParameter => new Lazy<RelayCommand<string>>(() => new RelayCommand<string>(WithParameter)).Value;
private void WithParameter(string info)
MessageBox.Show("Command Binding without parameter: " + info);
/// <summary>
/// 鼠标点击事件
/// </summary>
public RelayCommand<MouseButtonEventArgs> CmdMouseDown => new Lazy<RelayCommand<MouseButtonEventArgs>>(() => new RelayCommand<MouseButtonEventArgs>(MouseDown)).Value;
private void MouseDown(MouseButtonEventArgs e)
// 判断按下的鼠标按键
if (e.LeftButton == MouseButtonState.Pressed)
MessageBox.Show("Left mouse button down.");
else if (e.RightButton == MouseButtonState.Pressed)
MessageBox.Show("Right mouse button down.");
else if (e.MiddleButton == MouseButtonState.Pressed)
MessageBox.Show("Middle mouse button down.");
public ViewModelMain()
InitParams();
private void InitParams()
BindingText = "This is text";
BindingNumber = 3.14159;
BindingEnum = 0;
DataList = GetDataList();
private ObservableCollection<DataModel> GetDataList()
return new ObservableCollection<DataModel>
new DataModel{ Number = 1, Name = "AAA", Type=Gender.Male, IsChecked = true },
new DataModel{ Number = 2, Name = "BBB", Type=Gender.Female, IsChecked = false },
new DataModel{ Number = 3, Name = "CCC", Type=Gender.Female, IsChecked = false },
new DataModel{ Number = 4, Name = "DDD", Type=Gender.Female, IsChecked = true },
new DataModel{ Number = 5, Name = "EEE", Type=Gender.Male, IsChecked = true },
new DataModel{ Number = 6, Name = "FFF", Type=Gender.Male, IsChecked = false },
BoolToVisibilityConverter.cs
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace MvvmCmdBinding.Converter
/// ----------------------------------------------------------------
/// Author : Taosy.W
/// Created Time: 2021/8/6 23:26:03
/// Description : 布尔值转可见性
/// ------------------------------------------------------
/// Version Modified Time Modified By Modified Content
/// V1.0.0.0 2021/8/6 23:26:03 Taosy.W
public class BoolToVisibilityConverter : IValueConverter
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
if (value == null)
return Visibility.Visible;
if ((bool)value)
return Visibility.Visible;
return Visibility.Collapsed;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
throw new NotImplementedException();
EnumToBoolConverter.cs
using MvvmCmdBinding.Model;
using System;
using System.Globalization;
using System.Windows.Data;
namespace MvvmCmdBinding.Converter
/// ----------------------------------------------------------------
/// Author : Taosy.W
/// Created Time: 2021/8/8 20:31:31
/// Description :
/// ------------------------------------------------------
/// Version Modified Time Modified By Modified Content
/// V1.0.0.0 2021/8/8 20:31:31 Taosy.W
public class EnumToBoolConverter : IValueConverter
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
Gender mode = (Gender)value;
return mode == (Gender)int.Parse(parameter.ToString());
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
bool isChecked = (bool)value;
if (!isChecked)
return null;
return (Gender)int.Parse(parameter.ToString());
Gender.cs
namespace MvvmCmdBinding.Model
/// ----------------------------------------------------------------
/// Author : Taosy.W
/// Created Time: 2021/8/6 23:12:23
/// Description :
/// ------------------------------------------------------
/// Version Modified Time Modified By Modified Content
/// V1.0.0.0 2021/8/6 23:12:23 Taosy.W
public enum Gender
Male = 1,
Female
DataModel.cs
using GalaSoft.MvvmLight;
namespace MvvmCmdBinding.Model
/// ----------------------------------------------------------------
/// Author : Taosy.W
/// Created Time: 2021/8/6 23:41:07
/// Description :
/// ------------------------------------------------------
/// Version Modified Time Modified By Modified Content
/// V1.0.0.0 2021/8/6 23:41:07 Taosy.W
public class DataModel : ViewModelBase
private int number;
public int Number
get => number;
set => Set(ref number, value);
private string name;
public string Name
get => name;
set => Set(ref name, value);
private Gender type;
public Gender Type
get => type;
set => Set(ref type, value);
private bool isChecked;
public bool IsChecked