Wpf Controls Needed to Build Chess Application

Starting WPF project. Build own controls or buy?

The thing to remember is that WPF is very different from WinForms, you can do amazing things buy just re-skining existing controls, when you are starting your first WPF big project you don't yet understand WPF and you don't know the possibilities and pitfalls of the system.

I suggest you start developing the project without those controls and add them later, that way when you get around to adding those controls you will have a better feel of what controls you need and what controls are a trivial customization of an existing control.

If you need anything that isn't trivial it's better to buy - but only if the component you buy is good, so evaluate carefully.

and read Joel's "In Defense of Not-Invented-Here Syndrome" at http://www.joelonsoftware.com/articles/fog0000000007.html

WPF - best control to show chess moves?

I suggest using ListBox with TextBlock as ListBox.ItemTemplate and WrapPanel as ListBox.ItemsPanel.

You can also highlight the ListBox current selected item.

Chessboard in WPF

An alternative to the standard grid, is the use of a UniformGrid (msdn link).

It's probably more suited to this (in my opinion) as it will ALWAYS give you the same size cells.

used ala:

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

any of these answers will give you the results you desire.

What components do I need to build a Metro-style app in WPF?

You can use Elysium, which licensed under MIT license and included ApplicationBar and ToastNotification classes.

Creating chess GUI in WPF

I have implemented a chess board for my Silverlight Online Chess system.

Here is how I did it.

  1. I made a seperate user control for the chess board
  2. I added a grid 8x8 onto the control
  3. I then added 64 Borders shading each one a different color (dark squares and light squares) Make sure to name each one. Each of the borders were placed on the grid using the Grid.Row and Grid.Col properties.
  4. Within each Border I added an Image that will hold the chess piece image.
  5. You will have to code some methods around setting the image to the correct chess piece based on your current game state.
  6. Each of the Images received the same event (this is important), all 64 call the same piece of code:

    MouseLeftButtonDown="Image_MouseLeftButtonDown"
    MouseMove="Image_MouseMove"
    MouseLeftButtonUp="Image_MouseLeftButtonUp"

The idea behind these 3 events is that we record when I click on the image (MouseLeftButtonDown) that gets me the origin of the click, then I call the event as the mouse is moving, that allows me to update the screen as the piece is moving, and the last event I record when I let go of the mouse button (MouseLeftButtonUp), this allows me to get the destination and send the move to my chess engine. Once the move is recorded by the chess engine I just redraw the chess board.

private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Image image = (Image)sender;
Border border = (Border)image.Parent;

image.CaptureMouse();
isMouseCapture = true;
mouseXOffset = e.GetPosition(border).X;
mouseYOffset = e.GetPosition(border).Y;

var chessPiece = (Image) sender;
var chessSquare = (Border) chessPiece.Parent;

var row = (byte) (Grid.GetRow(chessSquare));
var column = (byte) (Grid.GetColumn(chessSquare) - 1);

if (engine.HumanPlayer == ChessPieceColor.White)
{
SelectionChanged(row, column, false);
}
else
{
SelectionChanged((byte)(7 - row), (byte)(7 - column), false);
}
}

SelectionChanged is my own method for recording what source square the user selected.
isMouseCapture is also my own variable for recording when the user started draging the piece.

private void Image_MouseMove(object sender, MouseEventArgs e)
{

Image image = (Image)sender;
Border border = (Border)image.Parent;

if (!currentSource.Selected)
{
image.ReleaseMouseCapture();
isMouseCapture = false;

translateTransform = new TranslateTransform();

translateTransform.X = 0;
translateTransform.Y = 0;

mouseXOffset = 0;
mouseYOffset = 0;
}

if (isMouseCapture)
{
translateTransform = new TranslateTransform();

translateTransform.X = e.GetPosition(border).X - mouseXOffset;
translateTransform.Y = e.GetPosition(border).Y - mouseYOffset;

image.RenderTransform = translateTransform;

CalculateSquareSelected((int)translateTransform.X, (int)translateTransform.Y, false);

}
}

In the above CalculareSquareSelected converts the pixels moved to where I think the piece is moving to in the 8x8 chess board. For example say I moved 100 pixels and the chess board square is only 50 pixels than I moved 2 chess board squares.

private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (translateTransform == null)
{
return;
}

Image image = (Image)sender;

image.ReleaseMouseCapture();
isMouseCapture = false;

if (translateTransform.X > 10 || translateTransform.Y > 10 || translateTransform.X < -10 || translateTransform.Y < -10)
{
CalculateSquareSelected((int)translateTransform.X, (int)translateTransform.Y, true);
}
translateTransform = new TranslateTransform();

translateTransform.X = 0;
translateTransform.Y = 0;

mouseXOffset = 0;
mouseYOffset = 0;

image.RenderTransform = translateTransform;

}

If you have any questions feel free to contact me.

Dynamically created shaped panel with nested controls (also dynamically created) inside, which also have custom shapes

You'll save yourself a lot of headache in future if you do things properly and use data-binding instead of manipulating the GUI elements directly, but if you insist...

You need to use the Visual Tree Helper to traverse the control in order to find the templated framework element. You may also may need to call ApplyTemplate first to make sure that your control has been templated and is ready to access:

yourTemplatedControl.ApplyTemplate();
var canvas = VisualTreeHelper.GetChild(yourTemplatedControl, 0) as Canvas;

var ellipse = new Ellipse();
ellipse.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
ellipse.VerticalAlignment = System.Windows.VerticalAlignment.Top;
ellipse.Width = 50;
ellipse.Height = 50;
ellipse.Margin = new Thickness(0, 0, 0, 50);
ellipse.Stroke = Brushes.Blue;
ellipse.StrokeThickness = 1.5;
ellipse.Fill = Brushes.Yellow;
canvas.Children.Add(ellipse);

In this code I've just assumed that the first element in the template would be a Canvas, in practice you might prefer to search the visual tree for your canvas element (see here and here for more info).

WPF - Add buttons in chess-like layout

Content control is StackPanel, Grid, Canvas etc. You need to place all of the controls inside of a content control, since Window or UserControl can only have one child control.

Xaml:

<StackPanel>
<Button/>
<Button/>
</StackPanel>

In your case c# code should look something like this:

StackPanel yourSP = new StackPanel(); // Creates a new content control.
Button button1 = new Button; // Creates buttons.
Button button2 = new Button;
this.AddChild(yourSP); // Adds StackPanel to your Window/UserControl
yourSP.Children.Add(button1); // Adds buttons to content control.
yourSP.Children.Add(button2);

It creates a new StackPanel which is a content control and adds it as a child to your Window/UserControl afterwards you add Buttons to your StackPanel.

Please refer here for more information regarding content controls.



Related Topics



Leave a reply



Submit