WPF MVVM ItemsControl 实现图形界面对象与后台代码解耦

代码结构
在这里插入图片描述

MainWindow.xaml

<Window x:Class="MVVM_Simple_Exercise.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MVVM_Simple_Exercise"
        Title="Car Management Window" Height="400" Width="600">
    <Grid>
        <ItemsControl ItemsSource="{Binding Cars}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style>
                    <Setter Property="Canvas.Left" Value="{Binding Left}" />
                    <Setter Property="Canvas.Top" Value="{Binding Top}" />
                </Style>
            </ItemsControl.ItemContainerStyle>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <!--<Ellipse Width="50" Height="50" Fill="Red"
                             Canvas.Left="{Binding Left}" Canvas.Top="{Binding Top}"/>-->
                    <Ellipse Width="50" Height="50" Fill="Red"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Windows;
using MVVM_Simple_Exercise.ViewModels;

namespace MVVM_Simple_Exercise
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            CarViewModel viewModel = new CarViewModel();
            this.DataContext = viewModel;
        }
    }
}

DelegateCommand.cs

using System;
using System.Windows.Input;

namespace MVVM_Simple_Exercise.Commands
{
    class DelegateCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            if (CanExecuteFunc == null)
            {
                return true;
            }
            return this.CanExecuteFunc(parameter);
        }

        public void Execute(object parameter)
        {
            if (ExecuteAction == null)
            {
                return;
            }
            this.ExecuteAction(parameter);
        }

        public Func<object,bool> CanExecuteFunc { get; set; }
        public Action<object> ExecuteAction { get; set; }
    }
}

CarModel.cs

using MVVM_Simple_Exercise.ViewModels;

namespace MVVM_Simple_Exercise.Models
{
    public class CarModel : NotificationObject
    {
        private double left;
        public double Left
        {
            get { return left; }
            set
            {
                //if (left != value)
                //{
                    left = value;
                    RaisePropertyChanged();
                //}
            }
        }

        private double top;
        public double Top
        {
            get { return top; }
            set
            {
                //if (top != value)
                //{
                    top = value;
                    RaisePropertyChanged();
                //}
            }
        }

        public void Move(double deltaX, double deltaY)
        {
            Left += deltaX;
            Top += deltaY;
        }
    }
}

CarViewModel.cs

using MVVM_Simple_Exercise.Models;
using System.Collections.ObjectModel;
using System.Timers;
using System.Windows;

namespace MVVM_Simple_Exercise.ViewModels
{
    public class CarViewModel : NotificationObject
    {
        private Timer timerCreate;
        private Timer timerMove;
        public ObservableCollection<CarModel> Cars { get; } = new ObservableCollection<CarModel>();

        public CarViewModel()
        {
            timerCreate = new Timer(5000); // 每秒执行一次
            timerCreate.Elapsed += Timer_Elapsed;
            timerCreate.Start();

            timerMove = new Timer(1000); // 每秒执行一次
            timerMove.Elapsed += Timer_ElapsedMove;
            timerMove.Start();
        }

        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            // 在定时器触发时创建新的小车对象
            Application.Current.Dispatcher.Invoke(() =>
            {
                var car = new CarModel();
                Cars.Add(car);
            });
        }

        private void Timer_ElapsedMove(object sender, ElapsedEventArgs e)
        {
            // 更新所有小车的位置
            foreach (var car in Cars)
            {
                car.Move(100, 0); // 每次移动10个像素
            }
        }
    }
}

NotificationObject.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace MVVM_Simple_Exercise.ViewModels
{
    public class NotificationObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void RaisePropertyChanged([CallerMemberName()] string propertyName = null/*告诉binding到底是那个属性它的值发生改变了*/)
        {
            if (propertyName != null) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); // binding关注的的确是这个property,赶紧将这个值传到界面上去
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值