WPF中的棋盘

5
多年来我一直在使用Winforms进行开发,现在我想转换到WPF并制作一个国际象棋棋盘。不幸的是,我不知道从哪里开始。使用WPF让我非常不确定,感觉自己又像个新手了。有人能概述一下基本的设计吗?我想我会从一个8x8的网格开始,使用矩形来表示方格,使用图像来表示棋子。然后呢?我有什么遗漏的吗?
编辑:这只涉及用户界面;背后发生的事情不是问题。

我有点惊讶,没有一个答案涵盖了如何在用户使用鼠标输入移动时“拖放”棋子的问题。那么这是在基于网格的棋盘上面叠加完成的吗?还是有其他方法实现? - BitTickler
5个回答

10

除了标准网格外,还可以使用 UniformGridmsdn链接)。

在我的看法中,它可能更适合此问题,因为它始终会给出相同大小的单元格。

用法示例:

<UniformgGrid Columns="8" Rows="8">
    <Control1/>
    <Control2/>
    <Control3/>
</UniformGrid>

任何一个答案都能给你想要的结果。


+1 没想到这一点。通常我的网格从来不是均匀的 :) - DenaliHardtail
是的,我也是。开始时读到过它,但很快就忘记了。 - serialhobbyist

7

象棋似乎非常适合WPF的MVVM代码模式。

Model将是象棋游戏的逻辑,听起来你已经掌握了这一点。 View将是游戏的WPF外观,ViewModel将是游戏的表示形式,View可以对其进行数据绑定。

对于视图,使用UniformGrid的ItemsControl将适用于游戏的2D表示。

这是一个开始(未经审核)

<ItemsControl ItemsSource="{Binding TheGame}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="8" Rows="8" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ContentControl Background="{Binding SquareColor}">
                <Path Data="{Binding PieceShape}" Fill="{Binding PieceColor}" />
            </ContentControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

为了使上述内容生效,您的ViewModel需要有一个ObservableCollection<ChessGridItem>,而ChessGridItem应该是一个DependencyObject,公开依赖属性SquareColorPieceColorPieceShape


如果我想使用Grid而不是UniformGrid - 我该如何将Grid.Column和Grid.Row属性绑定到方块的x和y坐标上? - CaptainProton
这个问题并没有太多意义。如果你想使用x/y坐标系,可以使用Canvas面板。数据绑定的语法很简单,但并不是非常有用。WPF的方式是让面板负责布局。看看这个例子,了解一下普通面板的强大之处 - http://www.beacosta.com/blog/?p=40 - Scott Weinstein
1
使用“坐标(coordinates)”时,我指的不是屏幕上的实际坐标,而是棋盘上的坐标(从0到7)。因此,我尝试了“<ContentControl Grid.Column="{Binding CoordinateX}"…”,但它没有起作用。也许我应该为此提出另一个问题。 - CaptainProton
我和CaptainProton有同样的问题 - 有人知道如何将坐标绑定到网格(或类似的控件)吗? - Pat

1

你可以使用XAML或代码来创建UI,效果相同。我最近开始使用WPF,并推荐使用XAML方法。虽然一开始有点吓人,但很快就会变得熟悉。对我来说,它感觉像是一种精心设计的UI设计方法,现在WinForms看起来就像是将.NET随便套用到以前的东西上。

你可以从拖放方式开始,但如果像我一样,你很快就会在XAML中工作,并使用设计表面进行视觉检查。

这可能不是我会做的方式,但如果你看过任何XML或HTML,即使你以前从未看过任何XAML,你也可以猜出它将显示什么:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="100" />
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition Height="100" />
        <RowDefinition Height="100" />
        <RowDefinition Height="100" />
        <RowDefinition Height="100" />
    </Grid.RowDefinitions>

    <Border Grid.Column="0" Grid.Row="0" Background="Black" />
    <Border Grid.Column="2" Grid.Row="0" Background="Black" />
    <Border Grid.Column="1" Grid.Row="1" Background="Black" />
    <Border Grid.Column="3" Grid.Row="1" Background="Black" />
</Grid>

1
“这可能不是我会做的方式,但是…”那么,你会怎么做呢? - DenaliHardtail
首先,我会认真考虑一下... :-) 首先,你需要考虑的是你对它的外观有多挑剔——这是一个学习练习还是一个独立的项目——它需要多漂亮?然后,你需要考虑游戏和棋盘的方法:每个方格是否会保持其状态,或者你会有一组棋子来保持它们的位置。你想要棋子移动时有花哨的过渡效果吗?等等。 - serialhobbyist
WPF的好处在于你可以将UI设计与编码分离,将Blend的副本和解决方案链接交给设计师,让他们完成这一部分,而你则可以专注于编写代码。当然,你们之间需要进行大量的沟通,但是他们会做出花哨的细节处理,而你则调整引擎。或者说,其他什么的。 - serialhobbyist

0

不,我认为你没有错过任何东西。那是一个很好的开端。

创建一个网格,然后添加列和行。然后将矩形放入交替单元格中(或图像)。我会为矩形的填充颜色和描边创建样式。这样,您可以在一个位置(样式定义)更改背景颜色,而不是为每个需要更改的单元格更改。

这是一个使用网格的非常基本的棋盘。请注意,我没有硬编码行和列的大小。这将保持比例并允许棋盘缩放。

    <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Name="A1"  />
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Rectangle Name="rectangle1"
               Stroke="Black" Fill="Aquamarine" />
</Grid>

0

我同意这里发布的所有示例,但我认为你可能会因WPF中完全不同的“数据”“模板”模型与WinForms紧密绑定的UI +数据模型而感到有些困惑。

从WinForm转换到WPF需要一定的学习曲线,我自己花了两年时间才开始在WPF中编写代码,因为我总是更喜欢在codebehind文件中工作。

我最好的猜测是,首先您必须了解WPF的“逻辑树”和“可视树”概念,在那里您将了解WPF UI元素和非UI元素(数据对象)如何在XAML中轻松连接而无需编写任何C#。

还有另一个最重要的概念,即“触发器”。

您需要创建的所有内容都是“数据”对象,它们将是您的棋子项目(King,Horse)等,派生自实现IPropertyChanged接口的一个公共基类,并实现像“CanBeKilled”,“IsPossibleTarget”之类的属性,这些属性可以简单地绑定在ListBox的ItemTemplate中,其中您的ListBox将保存当前选择。

ListBox的项面板模板可以是上述示例之一,在MouseOver时,您可以根据上述属性突出显示颜色或边框。当选择更改时,您需要更新ListBox中每个项目的布尔属性。

我刚刚看了你的编辑部分,我相信WPF中的Code Behind必须与WinForms不同且更简单,因为与WinForms相比,设计良好的WPF将比WinForm少90%的Code Behind。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接