C# WPF 实现躲避球小游戏

By jerryxjr1220 at 2023-09-28 • 0人收藏 • 432人看过

其实用的游戏底层与前面的五子棋是同一个,渲染不同而已,要是贴上不同图像可以模拟更多平面游戏,坦克大战,超级玛丽这种都不是问题。

screenshots.gif

竖过来,就变成《是男人就挑战100层》

捕获.PNG

//Model
using System;
using System.ComponentModel;
using CommunityToolkit.Mvvm.ComponentModel;

namespace WPFFlight.Models;

public partial class GameObject: ObservableObject
{
    public enum ObjectTypes
    {
        Space,
        Rock,
        Bullet,
        Enemy,
        Player,        
    }
    
    [ObservableProperty] private ObjectTypes _blockType;
    
    [ObservableProperty] private int _xPos;
    [ObservableProperty] private int _yPos;
    
    [ObservableProperty] private int _xPosActual;
    [ObservableProperty] private int _yPosActual;
    
    [ObservableProperty] private int _blockSize;
    [ObservableProperty] private int _speed;
    
    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        base.OnPropertyChanged(e);
        switch(e.PropertyName)
        {
            case "XPos":
                XPosActual = XPos * BlockSize;
                break;
            case "YPos":
                YPosActual = YPos * BlockSize;
                break;
        }
    }

    public GameObject(string _type, int _x, int _y, int _speed=1, int _blockSize=20)
    {
        switch (_type)
        {
            case "S":
                BlockType = ObjectTypes.Space;
                break;
            case "R":
                BlockType = ObjectTypes.Rock;
                break;
            case "B":
                BlockType = ObjectTypes.Bullet;
                break;
            case "E":
                BlockType = ObjectTypes.Enemy;
                break;
            case "P":
                BlockType = ObjectTypes.Player;
                break;
            default:
                throw new ArgumentException();
        }

        Speed = _speed;
        BlockSize = _blockSize;
        XPos = _x;
        YPos = _y;
    }
    
    
    public GameObject()
    {
        
    }
}
//ViewModel
using System;
using System.ComponentModel;
using System.Globalization;
using System.Threading;
using System.Windows.Data;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using WPFFlight.Models;
namespace WPFFlight.ViewModels;

public partial class MainViewModel: ObservableObject
{
    [ObservableProperty] private BindingList<GameObject> _uiLayout;
    [ObservableProperty] private int _blockSize;
    [ObservableProperty] private int _speed;
    [ObservableProperty] private int _level;
    public string[,] GameLayout { get; set; }
    
    public MainViewModel()
    {
        GameLayout = new string[10, 20]
        {
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "R", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "P", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
        };
        BlockSize = 20;
        Speed = 1;
        Level = 1;
        UiLayout = new BindingList<GameObject>();
        RenderLayout();
        //发送消息
        //WeakReferenceMessenger.Default.Send(new CustomizedMessage(new MessageModel()));
    }

    public void RenderLayout()
    {
        UiLayout.Clear();
        for (int x = 0; x < 10; x++)
        {
            for (int y = 0; y < 20; y++)
            {
                var current = GameLayout[x, y];
                UiLayout.Add(new GameObject(current, y, x, Speed, BlockSize));
            }
        }
    }

    public void Move()
    {
        int px = 0;
        int py = 0;
        for (int j = 0; j < 10; j++)
        {
            for (int i = 1; i < 20; i++)
            {
                if (GameLayout[j, i] == "P")
                {
                    px = j;
                    py = i;
                    GameLayout[j, i - 1] = "S";
                    continue;
                }
                GameLayout[j, i-1] = GameLayout[j, i];
            }

            var rand = new Random();
            var r = rand.Next(0, 21-Level);
            GameLayout[j, 19] = r < 19-Level ? "S" : "R";
        }

        GameLayout[px, py] = "P";
        RenderLayout();
    }
    
    public void MoveDown()
    {
        int px = 0;
        for (int j = 0; j < 10; j++)
        {
            if (GameLayout[j, 1] == "P")
            {
                px = j;
                GameLayout[j, 1] = "S";
            }
        }

        if (px >= 9) 
            GameLayout[px, 1] = "P";
        else
            GameLayout[px+1, 1] = "P";
        RenderLayout();
    }
    
    public void MoveUp()
    {
        int px = 0;
        for (int j = 0; j < 10; j++)
        {
            if (GameLayout[j, 1] == "P")
            {
                px = j;
                GameLayout[j, 1] = "S";
            }
        }

        if (px <= 0) 
            GameLayout[px, 1] = "P";
        else
            GameLayout[px-1, 1] = "P";
        RenderLayout();
    }
    
}

public class BorderValueConverter : IValueConverter
{
    public int Offset { get; set; } = 2;
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return int.Parse(value.ToString()) - Offset;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


//定义消息
// public class CustomizedMessage : ValueChangedMessage<MessageModel> // PropertyChangedMessage // RequestMessage ( Async + ..)
// {
//     public CustomizedMessage(MessageModel value) : base(value)
//     {
//     }
// }
<hc:GlowWindow x:Class="WPFFlight.Views.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:model="clr-namespace:WPFFlight.Models"
               xmlns:vm="clr-namespace:WPFFlight.ViewModels"
               xmlns:view="clr-namespace:WPFFlight.Views"
               xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
               xmlns:local="clr-namespace:WPFFlight"
               xmlns:hc="https://handyorg.github.io/handycontrol"
               d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
               mc:Ignorable="d"
               Title="Flight Fight" Height="240" Width="400" ResizeMode="NoResize"
               FontFamily="JetBrains Mono"
               FontSize="{StaticResource TextFontSize}">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        <!--<vm:BorderValueConverter Offset="0" x:Key="BorderValueConverter" />-->
    </Window.Resources>
    <hc:SimplePanel>
        <ScrollViewer x:Name="scrollViewer" VerticalScrollBarVisibility="Auto">
            <Grid Background="Black" Margin="0, 5">
                <ItemsControl ItemsSource="{Binding UiLayout}" MouseWheel="MainWindow_OnMouseWheel" >
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Canvas />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemContainerStyle>
                        <Style TargetType="ContentPresenter">
                            <Setter Property="Canvas.Left" Value="{Binding XPosActual}" />
                            <Setter Property="Canvas.Top" Value="{Binding YPosActual}" />
                        </Style>
                    </ItemsControl.ItemContainerStyle>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Border BorderBrush="DarkGray" BorderThickness="0">
                                <Border x:Name="UiCanvas"
                                        Width="{Binding BlockSize}"
                                        Height="{Binding BlockSize}" />
                            </Border>
                            <DataTemplate.Triggers>
                                <DataTrigger Binding="{Binding BlockType}" Value="0">
                                    <Setter TargetName="UiCanvas" Property="Background" Value="Black"></Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding BlockType}" Value="1">
                                    <Setter TargetName="UiCanvas" Property="Background" Value="Chocolate"></Setter>
                                    <Setter TargetName="UiCanvas" Property="CornerRadius" Value="8"></Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding BlockType}" Value="2">
                                    <Setter TargetName="UiCanvas" Property="Background" Value="Red"></Setter>
                                    <Setter TargetName="UiCanvas" Property="CornerRadius" Value="10"></Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding BlockType}" Value="3">
                                    <Setter TargetName="UiCanvas" Property="Background" Value="Cyan"></Setter>
                                    <Setter TargetName="UiCanvas" Property="CornerRadius" Value="9"></Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding BlockType}" Value="4">
                                    <Setter TargetName="UiCanvas" Property="Background" Value="White"></Setter>
                                    <Setter TargetName="UiCanvas" Property="CornerRadius" Value="9"></Setter>
                                </DataTrigger>
                            </DataTemplate.Triggers>
                        </DataTemplate>

                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </Grid>
        </ScrollViewer>
    </hc:SimplePanel>
</hc:GlowWindow>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using HandyControl.Controls;
using WPFFlight.Models;
using WPFFlight.ViewModels;
using MessageBox = HandyControl.Controls.MessageBox;

namespace WPFFlight.Views;

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : GlowWindow
{
    private MainViewModel mainViewModel;
    public MainWindow()
    {
        InitializeComponent();
        

        #region 注册并接受消息

        //WeakReferenceMessenger.Default.Register<CustomizedMessage>(this, (o, m) => { MessageBox.Show("Received!"); });

        #endregion
        
        
        mainViewModel = new MainViewModel();
        this.DataContext = mainViewModel;
        
    }


    private void MainWindow_OnMouseWheel(object sender, MouseWheelEventArgs e)
    {
        if(e.Delta>0) mainViewModel.MoveUp();
        else mainViewModel.MoveDown();
        mainViewModel.Move();
    }
    
}


3 个回复 | 最后更新于 2023-10-07
2023-10-05   #1

优化后版本《是男人就上100层》

using System;
using System.ComponentModel;
using CommunityToolkit.Mvvm.ComponentModel;
 
namespace WPFFly.Models;
 
public partial class GameObject: ObservableObject
{
    public enum ObjectTypes
    {
        Space,
        Rock,
        Bullet,
        Enemy,
        Player,        
    }
     
    [ObservableProperty] private ObjectTypes _blockType;
     
    [ObservableProperty] private int _xPos;
    [ObservableProperty] private int _yPos;
     
    [ObservableProperty] private int _xPosActual;
    [ObservableProperty] private int _yPosActual;
     
    [ObservableProperty] private int _blockSize;
    [ObservableProperty] private int _speed;
     
    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        base.OnPropertyChanged(e);
        switch(e.PropertyName)
        {
            case "XPos":
                XPosActual = XPos * BlockSize;
                break;
            case "YPos":
                YPosActual = YPos * BlockSize;
                break;
        }
    }
 
    public GameObject(string _type, int _x, int _y, int _speed=1, int _blockSize=20)
    {
        switch (_type)
        {
            case "S":
                BlockType = ObjectTypes.Space;
                break;
            case "R":
                BlockType = ObjectTypes.Rock;
                break;
            case "B":
                BlockType = ObjectTypes.Bullet;
                break;
            case "E":
                BlockType = ObjectTypes.Enemy;
                break;
            case "P":
                BlockType = ObjectTypes.Player;
                break;
            default:
                throw new ArgumentException();
        }
 
        Speed = _speed;
        BlockSize = _blockSize;
        XPos = _x;
        YPos = _y;
    }
     
     
    public GameObject()
    {
         
    }
}
using System;
using System.ComponentModel;
using System.Globalization;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Data;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using Microsoft.Xaml.Behaviors.Core;
using WPFFly.Models;
namespace WPFFly.ViewModels;
 
public partial class MainViewModel: ObservableObject
{
    [ObservableProperty] private BindingList<GameObject> _uiLayout;
    [ObservableProperty] private int _blockSize;
    [ObservableProperty] private int _speed;
    [ObservableProperty] private int _level;
    [ObservableProperty] private int _steps;
    public string[,] GameLayout { get; set; }
     
    public MainViewModel()
    {
        UiLayout = new BindingList<GameObject>();
        GameLayout = new string[10, 20]
        {
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "P", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
        };
        GameInit();
        //发送消息
        //WeakReferenceMessenger.Default.Send(new CustomizedMessage(new MessageModel()));

    }

    public void GameInit()
    {
        GameLayout = new string[10, 20]
        {
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "P", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "R", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
            {"S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S"},
        };
        Steps = 0;
        BlockSize = 20;
        Speed = 1;
        Level = 1;
        UiLayout = new BindingList<GameObject>();
        RenderLayout();
    }
 
    public void RenderLayout()
    {
        UiLayout.Clear();
        for (int x = 0; x < 10; x++)
        {
            for (int y = 0; y < 20; y++)
            {
                var current = GameLayout[x, y];
                UiLayout.Add(new GameObject(current, x, 19-y, Speed, BlockSize));
            }
        }
    }
 
    public void Move()
    {
        int px = 0;
        int py = 0;
        for (int j = 0; j < 10; j++)
        {
            for (int i = 1; i < 20; i++)
            {
                
                // 判断是否游戏结束
                if (GameLayout[j, i] == "R" && GameLayout[j, i - 1] == "P")
                {
                    MessageBox.Show($"Game Over! \r\n Level: {Level}", "Game Over",
                        MessageBoxButton.OK, MessageBoxImage.Stop);
                    GameInit();
                    return;                    
                }
                // 记录玩家坐标
                if (GameLayout[j, i] == "P")
                {
                    px = j;
                    py = i;
                    GameLayout[j, i - 1] = "S";
                    continue;
                }
                GameLayout[j, i-1] = GameLayout[j, i];
            }
            // 随机生成新一排的地图, 难度由level计算得到。 level越高,生成的石头越多。
            var rand = new Random();
            var r = rand.Next(0, 51-Level);
            GameLayout[j, 19] = r < 49-Level ? "S" : "R";
        }
        //把玩家坐标写回到界面中
        GameLayout[px, py] = "P";
        RenderLayout();
        //步数增加
        Steps += 1;
        // level随步数增加而增加
        Level = Steps / 10 + 1;
    }
    
    //滚轮移动后向左右移动
    public void MoveDown()
    {
        //Move();
        int px = 0;
        for (int j = 0; j < 10; j++)
        {
            if (GameLayout[j, 1] == "P")
            {
                px = j;
                GameLayout[j, 1] = "S";
            }
        }
 
        if (px >= 9) 
            GameLayout[px, 1] = "P";
        else
            GameLayout[px+1, 1] = "P";
        RenderLayout();
    }
    //滚轮移动后向左右移动
    public void MoveUp()
    {
        //Move();
        int px = 0;
        for (int j = 0; j < 10; j++)
        {
            if (GameLayout[j, 1] == "P")
            {
                px = j;
                GameLayout[j, 1] = "S";
            }
        }
 
        if (px <= 0) 
            GameLayout[px, 1] = "P";
        else
            GameLayout[px-1, 1] = "P";
        RenderLayout();
    }
     
}

public class BorderValueConverter : IValueConverter
{
    public int Offset { get; set; } = 2;
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return int.Parse(value.ToString()) - Offset;
    }
 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
 
 
//定义消息
// public class CustomizedMessage : ValueChangedMessage<MessageModel> // PropertyChangedMessage // RequestMessage ( Async + ..)
// {
//     public CustomizedMessage(MessageModel value) : base(value)
//     {
//     }
// }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using HandyControl.Controls;
using WPFFly.Models;
using WPFFly.ViewModels;
using MessageBox = HandyControl.Controls.MessageBox;
 
namespace WPFFly.Views;
 
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : GlowWindow
{
    private DispatcherTimer timer;
    private MainViewModel mainViewModel;
    public MainWindow()
    {
        InitializeComponent();

        #region 注册并接受消息
 
        //WeakReferenceMessenger.Default.Register<CustomizedMessage>(this, (o, m) => { MessageBox.Show("Received!"); });
 
        #endregion
        
        mainViewModel = new MainViewModel();
        this.DataContext = mainViewModel;
        timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromMilliseconds(500);
        timer.Tick += (sender, args) =>
        {
            mainViewModel.Move();
        };
         
        timer.Start();
    }
 
 
    private void MainWindow_OnMouseWheel(object sender, MouseWheelEventArgs e)
    {
        if(e.Delta>0) mainViewModel.MoveUp();
        else mainViewModel.MoveDown();
        //mainViewModel.Move();
    }
     
}
<hc:GlowWindow x:Class="WPFFly.Views.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:model="clr-namespace:WPFFly.Models"
               xmlns:vm="clr-namespace:WPFFly.ViewModels"
               xmlns:view="clr-namespace:WPFFly.Views"
               xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
               xmlns:local="clr-namespace:WPFFly"
               xmlns:hc="https://handyorg.github.io/handycontrol"
               d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
               mc:Ignorable="d"
               Title="{Binding Level, StringFormat=Level: {0}}" Height="440" Width="200" ResizeMode="NoResize"
               FontFamily="JetBrains Mono"
               FontSize="{StaticResource TextFontSize}">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        <!--<vm:BorderValueConverter Offset="0" x:Key="BorderValueConverter" />-->
    </Window.Resources>
    <hc:SimplePanel>
        <ScrollViewer x:Name="scrollViewer" VerticalScrollBarVisibility="Auto">
            <Grid Background="Black" Margin="0, 5">
                <ItemsControl ItemsSource="{Binding UiLayout}" MouseWheel="MainWindow_OnMouseWheel" >
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Canvas />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemContainerStyle>
                        <Style TargetType="ContentPresenter">
                            <Setter Property="Canvas.Left" Value="{Binding XPosActual}" />
                            <Setter Property="Canvas.Top" Value="{Binding YPosActual}" />
                        </Style>
                    </ItemsControl.ItemContainerStyle>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Border BorderBrush="DarkGray" BorderThickness="0">
                                <Border x:Name="UiCanvas"
                                        Width="{Binding BlockSize}"
                                        Height="{Binding BlockSize}" />
                            </Border>
                            <DataTemplate.Triggers>
                                <DataTrigger Binding="{Binding BlockType}" Value="0">
                                    <Setter TargetName="UiCanvas" Property="Background" Value="Black"></Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding BlockType}" Value="1">
                                    <Setter TargetName="UiCanvas" Property="Background" Value="Chocolate"></Setter>
                                    <Setter TargetName="UiCanvas" Property="CornerRadius" Value="8"></Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding BlockType}" Value="2">
                                    <Setter TargetName="UiCanvas" Property="Background" Value="Red"></Setter>
                                    <Setter TargetName="UiCanvas" Property="CornerRadius" Value="10"></Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding BlockType}" Value="3">
                                    <Setter TargetName="UiCanvas" Property="Background" Value="Cyan"></Setter>
                                    <Setter TargetName="UiCanvas" Property="CornerRadius" Value="9"></Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding BlockType}" Value="4">
                                    <Setter TargetName="UiCanvas" Property="Background" Value="White"></Setter>
                                    <Setter TargetName="UiCanvas" Property="CornerRadius" Value="9"></Setter>
                                </DataTrigger>
                            </DataTemplate.Triggers>
                        </DataTemplate>
 
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </Grid>
        </ScrollViewer>
    </hc:SimplePanel>
</hc:GlowWindow>


2023-10-07   #2

这种高频刷新重绘的一个更适合直接画吧

2023-10-07   #3

回复#2 @aubreychao :

这种其实不算高频,而且wpf本来就是绑定模式,只要绑定值有变化,刷新是自动的。

登录后方可回帖

登 录
信息栏
 私人小站

本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...