WPF控件需要建立应用棋 [英] WPF controls needed to build chess application

查看:116
本文介绍了WPF控件需要建立应用棋的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想建立一个国际象棋的应用程序。我在的地方(几乎)后端逻辑。但是我还没有对用户界面的工作很多。我打算用C#和我听到WPF是要走的路。

I am trying to build a chess application. I have the backend logic in place (almost). But I havent worked much on UIs. I plan to use C# and I hear WPF is the way to go.

您能给我指点至于如何打造的UI界面,并在它的各种硬币?我必须建立某种控制的硬币?另外,我应该用什么控制开发板?

Could you please give me pointers as to how to build the UI interface and the various coins over it? Will I have to build some kind of controls for the coins? Also, what control should I use to develop the board?

推荐答案

我要去另一射击在这个问题和实际显示你如何使用WPF都是这么做的。虽然被警告,如果你从来没有做过任何WPF之前,那么这可能起初是有点势不可挡,但希望它应该给一些想法是多么的数据驱动WPF是如何强大,它可能是,一旦你找到窍门吧。

I'm gonna have another shot at this question and actually show you how to do this properly with WPF. Be warned though, if you've never done any WPF before then this might be a bit overwhelming at first, but hopefully it should give some idea of just how data-driven WPF is and how powerful it can be once you get the hang of it.

首先,您需要创建一个WPF项目并运行的NuGet软件包管理器添加MVVM光包(或手动添加它,如果你喜欢)。接下来,您将要设置一对夫妇枚举来定义你的作品类型,一类代表在董事会一块的实际例子:

First you'll need to create a WPF project and run NuGet package manager to add the MVVM Light package (or add it manually if you prefer). Next you'll want to set up a couple of enums to define your piece type and a class to represent an actual instance of a piece on the board:

public enum PieceType
{
    Pawn,
    Rook,
    Knight,
    Bishop,
    Queen,
    King
}

public enum Player
{
    White,
    Black
}

public class ChessPiece : ViewModelBase
{
    private Point _Pos;
    public Point Pos
    {
        get { return this._Pos; }
        set { this._Pos = value; RaisePropertyChanged(() => this.Pos); }
    }

    private PieceType _Type;
    public PieceType Type
    {
        get { return this._Type; }
        set { this._Type = value; RaisePropertyChanged(() => this.Type); }
    }

    private Player _Player;
    public Player Player
    {
        get { return this._Player; }
        set { this._Player = value; RaisePropertyChanged(() => this.Player); }
    }
}



几乎一切都从这里上的其他人在XAML中完成。首先,你需要,如果你想创建主板本身棋盘刷,这可以是一个位图,但我会继续前进,创造一个几何绘图代替。需要放置在你的Window.Resources部分代码:

Almost everything else from here on is done in XAML. First you need to create a checkerboard brush for the board itself, this can be a bitmap if you like but I'll go ahead and create a geometry drawing instead. This code needs to be placed in your Window.Resources section:

<DrawingBrush x:Key="Checkerboard" Stretch="None" TileMode="Tile" Viewport="0,0,2,2" ViewportUnits="Absolute">
        <DrawingBrush.Drawing>
            <DrawingGroup>
                <GeometryDrawing Brush="Tan">
                    <GeometryDrawing.Geometry>
                        <RectangleGeometry Rect="0,0,2,2" />
                    </GeometryDrawing.Geometry>
                </GeometryDrawing>
                <GeometryDrawing Brush="Brown">
                    <GeometryDrawing.Geometry>
                        <GeometryGroup>
                            <RectangleGeometry Rect="0,0,1,1" />
                            <RectangleGeometry Rect="1,1,1,1" />
                        </GeometryGroup>
                    </GeometryDrawing.Geometry>
                </GeometryDrawing>
            </DrawingGroup>
        </DrawingBrush.Drawing>
    </DrawingBrush>



接下来你需要一个方式来选择基于你渲染一张图像。有很多方法可以做到这一点,但我要在这里做的方式是声明的影像风格,然后使用该选择基于片式和播放器相应的位图触发器。在这个例子中我只热链接的网站wpclipart一些剪贴画。 XAML的此块很长,但它只是在做同样的事情,每件类型:

Next up you'll need a way to select an image based on the piece you're rendering. There are many ways to do this but the way I'm going to do it here is to declare an Image style and then use triggers that select the appropriate bitmap based on the piece type and player. For this example I'll just hot-link to some clip-art on the wpclipart site. This block of XAML is long but it's just doing the same thing for each piece type:

<Style x:Key="ChessPieceStyle" TargetType="{x:Type Image}">
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Pawn}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/>
                </MultiDataTrigger.Conditions>  
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_pawn_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Rook}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_rook_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Knight}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_knight_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Bishop}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_bishop_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Queen}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_queen_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.King}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_king_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Pawn}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_pawn_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Rook}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_rook_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Knight}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_knight_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Bishop}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_bishop_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Queen}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_queen_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.King}"/>
                    <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_king_T.png" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>



而现在的主板本身。与上面的代码设置此位极短,我们只是要呈现一个ItemsControl(即产品清单),我们将设置容器为画布,我们将设置它的背景,我们的棋盘和每件我们将设置基础上,波什属性的位置。很显然,我们也将使用我们设置上面选择正确的图像渲染ChessPieceStyle影像风格:

And now the board itself. With the above code set up this bit is surprisingly short, we're just going to render an ItemsControl (i.e. a list of items), we'll set the container to be a canvas, we'll set it's background to our checkerboard and for each piece we'll set the position based on the Pos property. Obviously we'll also use the ChessPieceStyle Image style that we set up above to select the correct image to render:

<ItemsControl Name="ChessBoard">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas Width="8" Height="8" Background="{StaticResource Checkerboard}"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Width="1" Height="1">
                    <Image Width="0.8" Height="0.8" Style="{StaticResource ChessPieceStyle}" />                     
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Left" Value="{Binding Pos.X}" />
                <Setter Property="Canvas.Top" Value="{Binding Pos.Y}" />
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>



这就是它!现在,我们有我们需要渲染一个国际象棋棋盘的一切。剩下的工作就是创造我们的作品的数组,把它放在一个ObservableCollection(以便GUI得到更新时部分添加和删除),并把它绑定到我们的棋盘:

And that's it! We now have everything we need to render a chess board. All that remains is to create an array of our pieces, put it in an ObservableCollection (so that the GUI gets updates when pieces added and removed) and bind it to our chessboard:

this.ChessBoard.ItemsSource = new ObservableCollection<ChessPiece>
        {
            new ChessPiece{Pos=new Point(0, 6), Type=PieceType.Pawn, Player=Player.White},
            new ChessPiece{Pos=new Point(1, 6), Type=PieceType.Pawn, Player=Player.White},
            new ChessPiece{Pos=new Point(2, 6), Type=PieceType.Pawn, Player=Player.White},
            new ChessPiece{Pos=new Point(3, 6), Type=PieceType.Pawn, Player=Player.White},
            new ChessPiece{Pos=new Point(4, 6), Type=PieceType.Pawn, Player=Player.White},
            new ChessPiece{Pos=new Point(5, 6), Type=PieceType.Pawn, Player=Player.White},
            new ChessPiece{Pos=new Point(6, 6), Type=PieceType.Pawn, Player=Player.White},
            new ChessPiece{Pos=new Point(7, 6), Type=PieceType.Pawn, Player=Player.White},
            new ChessPiece{Pos=new Point(0, 7), Type=PieceType.Rook, Player=Player.White},
            new ChessPiece{Pos=new Point(1, 7), Type=PieceType.Knight, Player=Player.White},
            new ChessPiece{Pos=new Point(2, 7), Type=PieceType.Bishop, Player=Player.White},
            new ChessPiece{Pos=new Point(3, 7), Type=PieceType.King, Player=Player.White},
            new ChessPiece{Pos=new Point(4, 7), Type=PieceType.Queen, Player=Player.White},
            new ChessPiece{Pos=new Point(5, 7), Type=PieceType.Bishop, Player=Player.White},
            new ChessPiece{Pos=new Point(6, 7), Type=PieceType.Knight, Player=Player.White},
            new ChessPiece{Pos=new Point(7, 7), Type=PieceType.Rook, Player=Player.White},
            new ChessPiece{Pos=new Point(0, 1), Type=PieceType.Pawn, Player=Player.Black},
            new ChessPiece{Pos=new Point(1, 1), Type=PieceType.Pawn, Player=Player.Black},
            new ChessPiece{Pos=new Point(2, 1), Type=PieceType.Pawn, Player=Player.Black},
            new ChessPiece{Pos=new Point(3, 1), Type=PieceType.Pawn, Player=Player.Black},
            new ChessPiece{Pos=new Point(4, 1), Type=PieceType.Pawn, Player=Player.Black},
            new ChessPiece{Pos=new Point(5, 1), Type=PieceType.Pawn, Player=Player.Black},
            new ChessPiece{Pos=new Point(6, 1), Type=PieceType.Pawn, Player=Player.Black},
            new ChessPiece{Pos=new Point(7, 1), Type=PieceType.Pawn, Player=Player.Black},
            new ChessPiece{Pos=new Point(0, 0), Type=PieceType.Rook, Player=Player.Black},
            new ChessPiece{Pos=new Point(1, 0), Type=PieceType.Knight, Player=Player.Black},
            new ChessPiece{Pos=new Point(2, 0), Type=PieceType.Bishop, Player=Player.Black},
            new ChessPiece{Pos=new Point(3, 0), Type=PieceType.King, Player=Player.Black},
            new ChessPiece{Pos=new Point(4, 0), Type=PieceType.Queen, Player=Player.Black},
            new ChessPiece{Pos=new Point(5, 0), Type=PieceType.Bishop, Player=Player.Black},
            new ChessPiece{Pos=new Point(6, 0), Type=PieceType.Knight, Player=Player.Black},
            new ChessPiece{Pos=new Point(7, 0), Type=PieceType.Rook, Player=Player.Black}
        };

和这里的结果是:

< IMG SRC =htt​​p://i.stack.imgur.com/9o6fA.pngALT =WPF棋盘>

这似乎是很多工作只是画一个棋盘,但请记住,这是现在一个完全数据驱动界面....如果您添加或删除件或更改任何在片中你的作品阵列领域,那么这些变化将通过传播到立即前端。它也非常易于扩展,修改和添加额外的功能,如动画,3D,反射等,但也许是最令人印象深刻的是,我没有在为了做到这一点,在WPF创建任何自定义用户控件数据绑定机制是强大到足以支持这种东西外的开箱容易。

That might seem like a lot of work just to draw a chessboard but keep in mind that this is now a completely data-driven interface....if you add or remove pieces or change any of the fields in the piece in your piece array then those changes will propagate through to the front-end immediately. It's also very easy to expand, modify and add additional features such as animation, 3D, reflections etc. But perhaps the most impressive thing is that I didn't have to create any custom user controls at all in order to do this, the WPF data binding mechanism is powerful enough to support this kind of stuff out-of-the-box easily.

如果您需要任何进一步澄清和/或希望看到一个单独的项目然后通过各种手段让我知道。

If you need any further clarifications and/or would like to see a standalone project then by all means let me know.

这篇关于WPF控件需要建立应用棋的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆