WPF和MvvmLight框架学习记录,持续更新中

1. 简介

1.1 目前处于WPF和MvvmLight学习阶段,如有错误,请批评指正

1.2 关于MvvmLight

MvvmLight是一个轻量级框架,使用Model-View-ViewModel模式,分离前后端,使开发更加的高效。

2. 创建WPF项目

alt

框架选择.Net5.0

alt

3. MvvmLight包安装

3.1 管理NuGet程序包,搜索mvvmlight,选择如图所示的包安装

alt

4. 框架搭建

4.1 创建View、Model、ViewModel 3个文件夹

4.2 移动MainWindow.xaml

4.2.1 将MainWindow.xaml移动到View文件夹下,并修改其命名空间

alt

4.2.2 修改MainWindow.xaml第一行为

<Window x:Class="WpfMvvmLightApp.View.MainWindow"

4.2.3 修改MainWindow.xaml.cs的命名空间为WpfMvvmLightApp.View

4.2.4 修改App.xaml的StartupUrl为"View/MainWindow.xaml"

4.3 创建ViewModelLocator类

4.3.1 在ViewModel文件夹下创建ViewModelLocator类

4.3.3 App.xaml添加资源

<Application x:Class="WpfMvvmLightApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfMvvmLightApp"
             StartupUri="View/MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <vm:ViewModelLocator xmlns:vm="clr-namespace:WpfMvvmLightApp.ViewModel" x:Key="Locator" />
        </ResourceDictionary>
    </Application.Resources>
</Application>

4.4 创建MainViewModel

4.4.1 在ViewModel文件夹下创建MainViewModel类,继承自ViewModelBase

4.5 在ViewModelLocator注册关联MainViewModel

using GalaSoft.MvvmLight.Ioc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfMvvmLightApp.ViewModel
{
    public class ViewModelLocator
    {
        public ViewModelLocator()
        {
            SimpleIoc.Default.Register<MainViewModel>();
        }
        /// <summary>
        /// 主页viewmodel
        /// </summary>
        public MainViewModel MainVM
        {
            get
            {
                return SimpleIoc.Default.GetInstance<MainViewModel>();
            }
        }
    }
}

4.6 在MainWindow.xaml关联MainVM

4.6.1 在Windows标签添加属性DataContext

    <Window x:Class="WpfMvvmLightApp.View.MainWindow"
        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:WpfMvvmLightApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        DataContext="{Binding Source={StaticResource Locator}, Path=MainVM}">
    <Grid>

    </Grid>
</Window>

5. 编写界面和数据逻辑

5.1 创建一个Model

5.1.1 在Model文件夹创建一个MainModel类,用于管理数据和操作,需要继承ObservableObject类,并创建一些属性和方法

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace WpfMvvmLightApp.Model
{
    public class MainModel : ObservableObject
    {
        private string msg = "hello";

        public string Msg
        {
            get { return msg; }
            set
            {
                msg = value;
                //数据改变通知界面刷新,不加则界面不会改变,注意属性是Msg而不是msg,msg会导致递归死循环
                RaisePropertyChanged(() => Msg);
            }
        }

        private int val;

        public int Val
        {
            get { return val; }
            set
            {
                val = value;
                RaisePropertyChanged(() => Val);
            }
        }


        public RelayCommand AddCommand { get; set; }
        public RelayCommand<string> ShowInfoCommand { get; set; }

        public MainModel()
        {
            AddCommand = new RelayCommand(() => Add());
            ShowInfoCommand = new RelayCommand<string>(info => ShowInfo(info));
        }

        private void Add()
        {
            Val++;
        }
        private void ShowInfo(string info)
        {
            MessageBox.Show(info, "ShowInfo被触发");
        }
    }
}

5.2 直接在ViewModel关联数据和操作

5.2.1 这个和在Model中分开写类似,就是将Model中的内容都写到ViewModel中,可以自行感受下区别。

5.2.2 如果是在View.xaml.cs中用WPF的方式进行binding,那么在使用string等非引用类型的时候不能实现关联,需要用类进行包装。

5.3 在ViewModel中加入Model对象

using GalaSoft.MvvmLight;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WpfMvvmLightApp.Model;

namespace WpfMvvmLightApp.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        private MainModel model;

        public MainModel Model
        {
            get { return model; }
            set { model = value; }
        }

        public MainViewModel()
        {
            model = new MainModel();
        }

    }
}

5.4 在View中关联Model对象数据

5.4.1 xaml代码

<Window x:Class="WpfMvvmLightApp.View.MainWindow"
        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:WpfMvvmLightApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        DataContext="{Binding Source={StaticResource Locator}, Path=MainVM}">
    <Grid>
        <!--定义列和列宽-->
        <Grid.ColumnDefinitions>
            <!--*的表示比例-->
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <!--定义行和行高-->
        <Grid.RowDefinitions>
            <!--带px或者只有数字的表示像素-->
            <RowDefinition Height="80"/>
            <RowDefinition Height="80"/>
            <RowDefinition Height="80"/>
        </Grid.RowDefinitions>
        <!--在第0行第0列创建textbox,字体大小50,内容垂直居中,关联到Model的Msg属性-->
        <TextBox Grid.Row="0" Grid.Column="0" Text="{Binding Model.Msg}" FontSize="50" VerticalContentAlignment="Center"/>
        <!--创建Button,关联到Model的ShowInfoCommand方法,添加参数 "你好,世界!"-->
        <Button Grid.Row="0" Grid.Column="1" Content="ShowInfo" Command="{Binding Model.ShowInfoCommand}" CommandParameter="你好,世界!"/>
        <TextBox Grid.Row="1" Grid.Column="0" Text="{Binding Model.Val}" FontSize="50" VerticalContentAlignment="Center"/>
        <!--创建Button,关联到Model的ClickCommand方法-->
        <Button Grid.Row="1" Grid.Column="1" Content="增加" Command="{Binding Model.AddCommand}"/>
    </Grid>
</Window>

5.4.2 运行

点击ShowInfo按钮

alt

点击增加按钮,左侧数值从0变成1

alt

6. binding

6.1 binding翻译为绑定,容易造成误解,其实本意是关联

MvvmLight中使用binding更加的灵活,不像WPF需要在view.xaml.cs中的初始化方法中写界面和数据关联,MvvmLight直接可以在View.xaml中关联ViewModel中的model,因此也不一定要在view.xaml中指定控件的x:Name。

6.2 一些简单binding,比如5.4.1

Text="{Binding Model.Msg}"
Text="{Binding Model.Val}"
Command="{Binding Model.AddCommand}"
Command="{Binding Model.ShowInfoCommand}" CommandParameter="你好,世界!"

6.3 静态资源binding,如7.1.1

ItemsSource="{Binding Source={StaticResource MainTypeEnumKey}}"

7. resource

7.1 在view.xaml创建枚举类型的资源,ComboBox ItemSource关联此资源,DataGrid中的DataGridComboBoxColumn同理

7.1.1 代码

namespace WpfMvvmLightApp.Model
{
    public enum MainType
    {
        A,B,C
    }
}

<!--加到MainWindow的Window属性-->
xmlns:model="clr-namespace:WpfMvvmLightApp.Model"
xmlns:core="clr-namespace:System;assembly=mscorlib"

<!--加到MainWindow的Window Content-->
<Window.Resources>
    <ResourceDictionary>
        <!--MainType列表-->
        <ObjectDataProvider x:Key="MainTypeEnumKey" MethodName="GetValues" ObjectType="{x:Type core:Enum}">
            <ObjectDataProvider.MethodParameters>
                <!--枚举类所在的命名空间和类名-->
                <x:Type Type="model:MainType" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </ResourceDictionary>
</Window.Resources>

<!--关联到ComboBox ItemSource-->
<ComboBox Grid.Row="2" Grid.Column="0" ItemsSource="{Binding Source={StaticResource MainTypeEnumKey}}"/>

7.1.2 运行效果

alt

8. 关联的ViewMode-View之间的消息传递

8.1 ViewMode->View

8.1.1 使用DataContext

MainViewModel vm = (MainViewModel)DataContext;

8.2 View->ViewMode

8.2.1 直接通过属性通知

public string Msg
{
    get { return msg; }
    set
    {
        msg = value;
        //数据改变通知界面刷新,不加则界面不会改变,注意属性是Msg而不是msg,msg会导致递归死循环
        RaisePropertyChanged(() => Msg);
    }
}

9. 非关联的ViewMode-View或ViewMode-ViewMode或View-View之间的消息传递

9.1 使用Messenger,效率略低于关联,因此在关联的情况下不使用Messenger

9.1.1 在接收端初始化中注册方法

 Messenger.Default.Register<string>(this, "AddValue", msg =>Model.Add());

9.1.2 在发送端调用

Messenger.Default.Send("", "AddValue");

9.1.3 注意,此处"AddValue"的作用相当于一个key,为了理解方便写了魔法值,建议用一个MessengerToken类去管理这些魔法值,增加程序可读性,同时方便查找引用,例

public class MessengerToken
{
    /// <summary>
    /// 增加值
    /// </summary>
    public const string AddValue = "AddValue";
}

Messenger.Default.Register<string>(this, MessengerToken.AddValue, msg =>Model.Add());
Messenger.Default.Send("", MessengerToken.AddValue);

9.1.4 注意2,此方法传递必须带参数,如果方法没有参数,最好在Register的时候指定string类型,那么需要在Send时附带一个空字符串,禁止使用null传递,会匹配不到对应的方法。

好的,你的问题是关于WPF如何使用MvvmLight工程框架MvvmLight是一个轻量级的Mvvm框架,它可以帮助开发人员更容易地实现WPF应用程序Mvvm模式。下面是使用MvvmLight框架开发WPF应用程序的一些步骤: 1. 首先,在Visual Studio创建一个WPF应用程序项目。 2. 打开NuGet包管理器,搜索并安装MvvmLight库。 3. 在App.xaml.cs文件,添加以下代码以初始化MvvmLight框架: ``` public partial class App : Application { static App() { ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); SimpleIoc.Default.Register<MainViewModel>(); } protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var mainWindow = new MainWindow(); mainWindow.Show(); } } ``` 在上面的代码,我们使用SimpleIoc容器注册了一个MainViewModel,该容器将为我们提供视图模型的实例。 4. 创建一个MainWindow.xaml文件,并在其添加一个Button控件和一个TextBlock控件。 5. 在MainWindow.xaml.cs文件,添加以下代码以绑定Button控件的Command属性: ``` public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = ServiceLocator.Current.GetInstance<MainViewModel>(); } } ``` 6. 创建一个MainViewModel.cs文件,并添加一个实现ICommand接口的RelayCommand类,用于处理Button控件的点击事件。 7. 在MainViewModel.cs文件,添加一个用于更新TextBlock控件内容的属性。 8. 在MainWindow.xaml文件,使用数据绑定将TextBlock控件绑定到MainViewModel的属性。 到此,我们就完成了使用MvvmLight框架开发WPF应用程序的过程。在实际开发,我们可以使用MvvmLight框架来简化应用程序的开发过程,提高开发效率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摩特男爵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值