添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
【1.7 MVVM:数据绑定、命令绑定】WPF案例代码解析

【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