0

我有一个项目,我应该在其中制作一个小游戏,您可以在其中将小矩形拖放到网格中,然后填充该网格。我遇到了一个问题。制作网格并提前定义大小是没有问题的。但是当当前网格已被填充时,我需要一个不同大小的新网格。

然后我想起了我曾经用 Java 制作的俄罗斯方块游戏,其中网格是使用 2d 数组创建的,我们可以根据用户输入调整其大小。我在重新格式化硬盘时丢失了项目。

问题是我不知道是否可以使用 WPF 和 C# 在画布上“绘制”一个数组,或者是否有一种简单的方法可以根据我将制作的函数(函数并不重要,因为它将根据分数定义行和列大小)。我已将此网格设置为用户控件,并且必须适用以下内容:

该网格不能大于 300 x 300(我可能会使其更大),这意味着行和列应该相应地缩放(如果可能的话)。

制作网格后,我认为需要拖放到网格中的较小矩形可以由较小的数组组成。然后,当您放下它时,您将网格的值从“1”更改为“2”。当网格中的所有位置都用“2”填充时,你会得到一个新的网格来填充(如果可以用数组来填充的话)

我真的希望有人能够帮助我,因为我不知道如何做到这一点,而我在互联网上唯一能找到的就是如何将拖放功能添加到项目中。

4

1 回答 1

5

忘记java。它又旧又笨又没用。它甚至没有属性。更不用说 WPF 提供的DataBinding功能了,更不用说 LinQ 的美妙之处了。

这是我对您描述的内容的看法:

<Window x:Class="MiscSamples.SquaresGameSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Forget java. It's a crappy dinousaur." Height="300" Width="300">
    <DockPanel>
        <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="2">
            <TextBlock Text="Rows:"/>
            <Slider Maximum="100" Minimum="10" Value="{Binding Rows}" Width="200"/>
            <TextBlock Text="Columns:"/>
            <Slider Maximum="100" Minimum="10" Value="{Binding Columns}" Width="200"/>
        </StackPanel>

        <ListBox Margin="0,0,20,0" Width="50" DockPanel.Dock="Left" ItemsSource="{Binding Numbers}">
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="OnItemMouseDown"/>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>

        <ItemsControl ItemsSource="{Binding Squares}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Rows="{Binding Rows}" Columns="{Binding Columns}"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="DarkGray" BorderThickness="1"
                            Background="#05FFFFFF" AllowDrop="True"
                            Drop="OnDrop">
                        <TextBlock VerticalAlignment="Center"
                                   HorizontalAlignment="Center"
                                   Text="{Binding Value}"/>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </DockPanel>
</Window>

代码背后:

 public partial class SquaresGameSample : Window
    {
        public SquaresGameSample()
        {
            InitializeComponent();
            DataContext = new SquaresGameViewModel();
        }

        private void OnDrop(object sender, DragEventArgs e)
        {
            var item = sender as FrameworkElement;
            if (item == null)
                return;

            var square = item.DataContext as Square;
            if (square == null)
                return;

            var number = (int)e.Data.GetData(typeof (int));
            square.Value = number;
        }

        private void OnItemMouseDown(object sender, MouseEventArgs e)
        {
            var item = sender as ListBoxItem;
            if (item == null)
                return;

            DragDrop.DoDragDrop(sender as DependencyObject, item.DataContext, DragDropEffects.Move);
        }
    }

视图模型:

 public class SquaresGameViewModel: PropertyChangedBase
    {
        private ObservableCollection<Square> _squares;
        public ObservableCollection<Square> Squares
        {
            get { return _squares ?? (_squares = new ObservableCollection<Square>()); }
        }

        private int _rows;
        public int Rows
        {
            get { return _rows; }
            set
            {
                _rows = value;
                OnPropertyChanged("Rows");
                CreateSquares();
            }
        }

        private int _columns;
        public int Columns
        {
            get { return _columns; }
            set
            {
                _columns = value;
                OnPropertyChanged("Columns");
                CreateSquares();
            }
        }

        public List<int> Numbers { get; set; }

        public SquaresGameViewModel()
        {
            _rows = 10;
            _columns = 10;
            Numbers = Enumerable.Range(1, 20).ToList();
            CreateSquares();
        }

        private void CreateSquares()
        {
            Squares.Clear();

            Enumerable.Range(0, Rows)
                      .SelectMany(x => Enumerable.Range(0, Columns)
                                                 .Select(y => new Square { Row = x, Column = y }))
                      .ToList().ForEach(Squares.Add);
        }
    }

数据项:

public class Square: PropertyChangedBase
{
    public int Row { get; set; }

    public int Column { get; set; }

    private int _value;
    public int Value
    {
        get { return _value; }
        set
        {
            _value = value;
            OnPropertyChanged("Value");
        }
    }
}

PropertyChangedBase(MVVM Helper 类):

    public class PropertyChangedBase:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            Application.Current.Dispatcher.BeginInvoke((Action) (() =>
                                                                     {
                                                                         PropertyChangedEventHandler handler = PropertyChanged;
                                                                         if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
                                                                     }));
        }
    }

结果:

在此处输入图像描述

  • 单击并拖动左侧的数字并将它们放在任何正方形上。号码将被放置在 Square 内。
  • 移动滑块并注意UniformGrid的行和列如何变化。全部通过数据绑定。
  • 无需在代码中创建或操作 UI 元素。一切都是通过 DataBinding 完成的。
  • 分辨率独立性。这就是 WPF 提供的。一切都被拉伸到包含的窗口大小。
  • MVVM = “只是简单,简单的属性和INotifyPropertyChanged。这就是在 WPF 中编程的方法。不需要复杂的事件“听众”(不管是什么)或任何类似的蹩脚的东西。
  • 只需将我的代码复制并粘贴到 a 中File -> New -> WPF Application,然后自己查看结果。
  • 如果您需要进一步的帮助,请告诉我。
  • WPF 摇滚。其他一切要么没有,要么完全糟透了。
于 2013-05-15T16:35:20.493 回答