C#之MVVM框架实现示例

考完研来公司实习一段时间,初学C#及MVVM,今日予以小记。
庚子年腊月初二

整体文件结构如下:
在这里插入图片描述
建立数据库,添加相关数据:
在这里插入图片描述
Person.cs代码://建立底层对应于数据库的数据模型

using System;
using System.Collections.Generic;
using System.Text;

namespace rereview.Models
{
    //Underlying data model
    public class PersonModel
    {
        public int ID { get; set; }
        public string NAME { get; set; }
        public int AGE { get; set; }
        public string Sex { get; set; }
    }
}

PersonService.cs代码://与数据库建立链接及操作数据库

using System;
using System.Collections.Generic;
using System.Text;
using rereview.Models;
using System.Data;
using System.Data.SQLite;
using Dapper;
using System.Linq;

namespace rereview.Services
{
    //define common interface
    public interface IPersonService
    {
        IList<PersonModel> GetAll();
    }
    public class PersonService:IPersonService
    {
        //DB connect and operate
        IDbConnection conn;//System.Data
        //operate
        public IList<PersonModel> GetAll()
        {
            string sql = "select * from Person";
            var ls = conn.Query<PersonModel>(sql);//Dapper
            return ls.ToList();//System.Linq
        }
        //connect
        public PersonService()
        {
            string connectionStr = "data source=E:\\demo.db";
            conn = new SQLiteConnection(connectionStr);//System.Data.SQLite

        }
    }
}

App.xaml.cs代码://PersonViewModel中需使用到container容器

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using Unity;//容器,将方法全项目可用
using rereview.Services;

namespace rereview
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public static UnityContainer container;//Unity
        //rewrite OnStartup
        protected override void OnStartup(StartupEventArgs e)
        {
            //formly register to Unity
            container = new UnityContainer();
            container.RegisterType<IPersonService, PersonService>();
            base.OnStartup(e);
        }
    }
}

PersonViewModel.cs代码://承前启后

using System;
using System.Collections.Generic;
using System.Text;
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
using System.Collections.ObjectModel;
using rereview.Models;
using rereview.Services;
using System.Threading.Tasks;
using Unity;

namespace rereview.ViewModels
{
    public class PersonViewModel: ViewModelBase//DevExpress.Mvvm
    {
        public ObservableCollection<PersonModel> Persons//System.Collections.ObjectModel
        {
            //Set the Person property to be returned
            get { return this.GetValue<ObservableCollection<PersonModel>>(nameof(Persons)); }
            set { this.SetValue<ObservableCollection<PersonModel>>(value,nameof(Persons)); }
        }
        [Command]//DevExpress.Mvvm.DataAnnotations
        public async void Query()
        {
            var res = await Task<IList<PersonModel>>.Factory.StartNew(() =>
            {
                var ls = service.GetAll();
                return ls;
            });
            //formal assignment
            Persons = new ObservableCollection<PersonModel>(res);
        }
        //Parses the contents of the container and assigns them to the property service
        private IPersonService service => App.container.Resolve<IPersonService>();
    }
}

index.xaml代码://前端页面展示

<UserControl x:Class="rereview.Views.index"
             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:rereview.Views"
             xmlns:vm="clr-namespace:rereview.ViewModels"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.DataContext>
        <vm:PersonViewModel/>
    </UserControl.DataContext>
    <Grid>
        <!--Row defination-->
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <!--Binding the button with the QueryCommand in PersonViewModel-->
        <Button Content="刷新" Height="30" Command="{Binding QueryCommand}"></Button>
        <!--省略Grid.Row=0-->
        <!--Binding the properties defined in PersonViewModel-->
        <ItemsControl Grid.Row="1" ItemsSource="{Binding Persons}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <StackPanel.Resources>
                            <Style TargetType="TextBlock">
                                <Setter Property="Foreground" Value="green"></Setter>
                                <Setter Property="FontSize" Value="25"></Setter>
                                <Setter Property="FontWeight" Value="Bold"></Setter>
                            </Style>
                        </StackPanel.Resources>
                        <TextBlock Text="{Binding NAME}"></TextBlock>
                        <TextBlock Text="{Binding AGE}"></TextBlock>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</UserControl>

最后App.xaml中修改启动页面:

<Application x:Class="rereview.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:rereview"
             StartupUri="Views/index.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

展示效果:
在这里插入图片描述

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我会尽力回答你的问题。 首先,MVVM框架是一种用于构建WPF应用程序的设计模式,它将应用程序分为三个部分:模型(Model)、视图(View)和视图模型(ViewModel)。模型是应用程序的数据和业务逻辑,视图是用户界面,而视图模型是连接模型和视图的中介。 接下来,我们来实现鼠标操作画圆和旋转矩形的功能。首先,在视图模型中创建两个命令,一个用于画圆,一个用于旋转矩形。在命令的Execute方法中,我们可以通过鼠标事件获取到鼠标的位置,然后根据这个位置绘制圆或者矩形。 下面是一个简单的示例代码: ```csharp public class MainViewModel : INotifyPropertyChanged { public ICommand DrawCircleCommand { get; set; } public ICommand RotateRectangleCommand { get; set; } private Point _lastPosition; private ObservableCollection<Shape> _shapes = new ObservableCollection<Shape>(); public ObservableCollection<Shape> Shapes { get { return _shapes; } set { _shapes = value; OnPropertyChanged(nameof(Shapes)); } } public MainViewModel() { DrawCircleCommand = new RelayCommand(DrawCircle); RotateRectangleCommand = new RelayCommand(RotateRectangle); } private void DrawCircle(object obj) { var args = obj as MouseEventArgs; if (args != null) { var position = args.GetPosition(null); var radius = 50; var circle = new Ellipse { Width = radius, Height = radius, Fill = Brushes.Red }; Canvas.SetLeft(circle, position.X - radius / 2); Canvas.SetTop(circle, position.Y - radius / 2); Shapes.Add(circle); } } private void RotateRectangle(object obj) { var args = obj as MouseEventArgs; if (args != null) { var position = args.GetPosition(null); var width = 100; var height = 50; var rectangle = new Rectangle { Width = width, Height = height, Fill = Brushes.Green, RenderTransformOrigin = new Point(0.5, 0.5) }; Canvas.SetLeft(rectangle, position.X - width / 2); Canvas.SetTop(rectangle, position.Y - height / 2); var transform = new RotateTransform { Angle = 0 }; rectangle.RenderTransform = transform; Shapes.Add(rectangle); var animation = new DoubleAnimation { From = 0, To = 360, Duration = new Duration(TimeSpan.FromSeconds(5)), RepeatBehavior = RepeatBehavior.Forever }; transform.BeginAnimation(RotateTransform.AngleProperty, animation); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public class RelayCommand : ICommand { private Action<object> _execute; private Func<object, bool> _canExecute; public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null) { _execute = execute; _canExecute = canExecute; } public bool CanExecute(object parameter) { return _canExecute == null || _canExecute(parameter); } public void Execute(object parameter) { _execute(parameter); } public event EventHandler CanExecuteChanged; public void RaiseCanExecuteChanged() { CanExecuteChanged?.Invoke(this, EventArgs.Empty); } } ``` 在这个示例代码中,我们创建了一个MainViewModel类,其中包含了两个命令DrawCircleCommand和RotateRectangleCommand,分别用于绘制圆和旋转矩形。当用户在画布上单击鼠标时,会触发对应的命令,并通过鼠标事件获取到鼠标位置,然后创建相应的形状并添加到Shapes集合中。可以通过绑定Shapes集合到画布上,将绘制的形状显示在界面上。 以上是一个简单的实现,具体的实现方式可以根据自己的需求进行调整和优化。希望能对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值