I'm working in a program which contains a canvas ,
This canvas includes some shapes and RuleLines ,
I added a grid to the canvas and it looked like this
the problem is the program is not smooth when I Manipulate or Zoom this canvas,
this is the Grid code in C# :
public void GridPartitions (Grid grid)
{
for (int ii = 0; ii < 50; ii++)
{
MyGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(20) });
MyGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(20) });
}
for (int row = 0; row < 50; row++)
{
for(int coulmn = 0; coulmn < 50; coulmn++)
{
var PartitionRectangle = new Rectangle();
PartitionRectangle.Stroke = new SolidColorBrush() { Color = Color.FromArgb(255, 0, 0, 0) };
PartitionRectangle.StrokeThickness = 0.2;
grid.Children.Add(PartitionRectangle);
Grid.SetRow(PartitionRectangle, row);
Grid.SetColumn(PartitionRectangle, coulmn);
}
}
}
However in Microsoft OneNote UWP
it has this option and it runs very smooth whatever the the number of the RuleLines and looks like this :
Any ideas to Improve My Code ?
Thank You.
here is My new Code .. Its better But still not smooth
I tried to Make everything in OOP as much as possible
XAML:
<Canvas Name="MyCanvas01" Background="Transparent"
MinWidth="2500" MinHeight="720"
Width="2500" Height="720"
HorizontalAlignment="Left" VerticalAlignment="Top"
RenderTransformOrigin="0.5,0.5"
ManipulationDelta="MyCanvas01_ManipulationDelta" ManipulationMode="All"
SizeChanged="MyCanvas01_SizeChanged">
<ItemsControl ItemsSource="{x:Bind HorizontalLines}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line X1="{Binding From.X}" Y1="{Binding From.Y}"
X2="{Binding ElementName=MyCanvas01, Path=Width}" Y2="{Binding To.Y}"
Stroke="black" StrokeThickness="0.5"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{x:Bind VerticalLines}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line X1="{Binding From.X}" Y1="{Binding From.Y}"
X2="{Binding To.X }" Y2="{Binding ElementName=MyCanvas01, Path=Height}"
Stroke="black" StrokeThickness="0.5"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="st01"/>
<TranslateTransform x:Name="TT01" />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
C#:
public void DrawMissingLines(ObservableCollection<LineBindingPointsClass> lines, double missingLines, Point from, Point to ,int gg)
{
if (missingLines > 0)
{
for (int ii = 0; ii < missingLines; ii++)
{
lines.Add(new LineBindingPointsClass() { From = from , To = to });
if (gg == 1)
{
from.X += 25;
to.X += 25;
}
else if (gg == 2)
{
from.Y += 25;
to.Y += 25;
}
}
}
else if (missingLines < 0)
{
for (int ii = 0; ii < -missingLines; ii++)
{
lines.Remove(lines.Last());
}
}
}
private void MyCanvas01_SizeChanged(object sender, SizeChangedEventArgs e)
{
Canvas SizedCanvas = (Canvas)sender;
double missingVerticalLines, MissingHorizontalLines;
missingVerticalLines = (Math.Floor(SizedCanvas.Width) - VerticalLines.Count() * 25 ) / 25;
MissingHorizontalLines = (Math.Floor(SizedCanvas.Height) - HorizontalLines.Count() * 25) / 25;
DrawMissingLines(VerticalLines, missingVerticalLines,
new Point(VerticalLines.Count()*25 , 0),
new Point(VerticalLines.Count() * 25 , SizedCanvas.Height ),1);
DrawMissingLines(HorizontalLines, MissingHorizontalLines
, new Point(0,HorizontalLines.Count() * 25 ),
new Point( SizedCanvas.Width, HorizontalLines.Count() * 25) ,2);
}
For smooth zooming and Support gestures and (Ctrl + MouseWheel) you can put the canvas inside ScrollViewer.
Here is example Code:
<ScrollViewer ZoomMode="Enabled" ZoomSnapPointsType="Mandatory">
<Canvas Background="White" RenderTransformOrigin="0.5,0.5"
ManipulationDelta="MyCanvas_ManipulationDelta" ManipulationMode="All" CacheMode="BitmapCache">
<Rectangle Width="500" Height="500" Fill="Black"/>
</Canvas>
</ScrollViewer>
actually its very smooth
Now I'm working on adding adaptive Grid
here is the final code
working perfect
smooth and adaptive ,the background grids are updating according to the Canvas size change
I added two borders
the background is LinearGradientBrush for each border ,,........
enough talking and here is the Code:
<ScrollViewer Name="BorderScrollViewer" ZoomMode="Enabled" ZoomSnapPointsType="Mandatory"
HorizontalScrollMode="Disabled"
VerticalScrollMode="Disabled"
VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled"
ManipulationDelta="MyCanvas01_ManipulationDelta" ManipulationMode="All">
<Canvas Name="MyCanvas01" Background="White"
MinWidth="1200" MinHeight="720"
Width="1200" Height="720"
HorizontalAlignment="Left" VerticalAlignment="Top"
RenderTransformOrigin="0.5,0.5"
ManipulationDelta="MyCanvas01_ManipulationDelta" ManipulationMode="All"
SizeChanged="MyCanvas01_SizeChanged"
>
<Border VerticalAlignment="Stretch"
Width="{Binding ElementName=MyCanvas01,Path=Width}"
Height="{Binding ElementName=MyCanvas01,Path=Height}">
<Border.Background>
<LinearGradientBrush EndPoint="25,0" SpreadMethod="Repeat" MappingMode="Absolute" StartPoint="-25,0">
<LinearGradientBrush.RelativeTransform>
<CompositeTransform CenterY="0.5" CenterX="0.5" />
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="Transparent" Offset="0.53"/>
<GradientStop Color="Transparent" Offset="0.48"/>
<GradientStop Color="#FF320064" Offset="0.49"/>
<GradientStop Color="#FF320061" Offset="0.51"/>
<GradientStop Color="#FF320068" Offset="0.51"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<Border VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Width="{Binding ElementName=MyCanvas01,Path=Width}"
Height="{Binding ElementName=MyCanvas01,Path=Height}" >
<Border.Background>
<LinearGradientBrush EndPoint="0,25" SpreadMethod="Repeat" MappingMode="Absolute" StartPoint="0,-25">
<LinearGradientBrush.RelativeTransform>
<CompositeTransform CenterY="0.5" CenterX="0.5"/>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="Transparent" Offset="0.53"/>
<GradientStop Color="Transparent" Offset="0.48"/>
<GradientStop Color="#FF320064" Offset="0.49"/>
<GradientStop Color="#FF320061" Offset="0.51"/>
<GradientStop Color="#FF320068" Offset="0.51"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<Canvas.RenderTransform>
<TransformGroup>
<TranslateTransform x:Name="TT01" />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
</ScrollViewer>
Related
When I hover over the button, it will turn aqua, however it does not switch back to black once removing the cursor.
I am new to C# and I'm trying to get a grasp of the basic application functions. They seem very different from Java's Swing and JavaFX.
private void Mouse_Move(object sender, MouseEventArgs e)
{
var element = (UIElement) e.Source;
var c = Grid.GetColumn(element);
var r = Grid.GetRow(element);
if (c == 0 && r == 0)
{
MenuButton.Fill = Brushes.Aqua;
}
else
{
MenuButton.Fill = Brushes.Black;
}
}
<Grid ShowGridLines="False" Background="#282828">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="68"></RowDefinition>
</Grid.RowDefinitions>
<Rectangle Grid.Column="0" Grid.RowSpan="1000">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#1c1c1c" Offset="0"/>
<GradientStop Color="#1c1c1c" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="MenuButton" MouseMove="Mouse_Move" Grid.Column="0" Grid.Row="0">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#1c1c1c" Offset="0"/>
<GradientStop Color="#1c1c1c" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ToggleButton Click="Button_Click" Grid.Row="0" Grid.Column="0" Height="32" Width="32" Checked = "HandleCheck" Unchecked = "HandleUnchecked">
<ToggleButton.Template>
<ControlTemplate>
<Image Width="32" Height="32" Source="Resources/menu.png"></Image>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
</Grid>
Use MouseLeave and MouseEnter instead of MouseMove
XAML
<Rectangle x:Name="MenuButton" MouseEnter="Mouse_Enter" Grid.Column="0" Grid.Row="0" MouseLeave="Mouse_Leave">
C#
private void Mouse_Enter(object sender, MouseEventArgs e)
{
var element = (UIElement) e.Source;
var c = Grid.GetColumn(element);
var r = Grid.GetRow(element);
if (c == 0 && r == 0)
{
MenuButton.Fill = Brushes.Aqua;
//Change fill to Aqua when the cursor enters
}
}
private void Mouse_Leave(object sender, MouseEventArgs e)
{
var element = (UIElement) e.Source;
var c = Grid.GetColumn(element);
var r = Grid.GetRow(element);
if (c == 0 && r == 0)
{
MenuButton.Fill = Brushes.Black;
//Change fill to Black when the cursor leaves
}
}
I have to do a drag and drop application listView to code-generated grid.
So I have done a test program and that works
here is the xaml
<Grid Margin="0,0,-61.6,0.4">
<ListView x:Name="lwOne" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown" Background="Bisque" Margin="16,65,340.2,22">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" Width="250" VerticalAlignment="Top"></WrapPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
<Grid Name="grdMain" Drop="Grid_Drop" Background="AliceBlue" AllowDrop="True" Margin="380,65,81.2,62"/>
Now I have to migrate all this to my real application Which looks like that
So from how the cursor looks like i can see that the drag and drop is not allowed on the grid but it is on the tiny border of each cell.
So the problem is not doing d&d but ALLOWING to it
here is the xaml. The source listView is lvAllowedPPtab2, the destination grid is grdPalletTab2
<TabItem Name="tabItem2" HorizontalAlignment="Center" Height="80" MouseLeftButtonUp="TabItem_MouseLeftButtonUp" FontSize="{StaticResource TOOLTIP_FONTSIZE}" IsSelected="false" >
<TabItem.Header>
<StackPanel>
<TextBlock Text="" FontSize="{StaticResource TAB_FONTSIZE}"/>
<TextBlock Name="tbTab2" Visibility="Hidden" FontSize="{StaticResource BUTTON_FONTSIZE}" />
</StackPanel>
</TabItem.Header>
<TabItem.Background>
<ImageBrush/>
</TabItem.Background>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border x:Name="Border1Tab2" BorderBrush="Gainsboro" BorderThickness="5" Width="200" Margin="10,10,10,10" >
<StackPanel Margin="-1.8,-0.8,2.2,1.4">
<ListBox x:Name="lbxPalletsTab2" Background="{x:Null}" BorderBrush="{x:Null}" Height="600" SelectionChanged="ListBox_SelectionChanged" Margin="12,10.2,8.4,10.4" />
</StackPanel>
</Border>
<Border x:Name="Border2Tab2" BorderBrush="Gainsboro" MinWidth="150" BorderThickness="5" Grid.Column="1" Margin="10,10,10,10">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300px"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid HorizontalAlignment="Stretch" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="50px"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="tbkPPtab2" Grid.Row="0" FontSize="22" Background="{x:Null}" FontWeight="Black" Text="---" HorizontalAlignment="Center" VerticalAlignment="Bottom"></TextBlock>
<ListView x:Name="lvAllowedPPtab2" Grid.Row="1" FontSize="12" Background="{x:Null}" BorderBrush="Gainsboro" BorderThickness="5" Margin="10" VerticalAlignment="Stretch" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown">
<ListView.ItemsPanel >
<ItemsPanelTemplate >
<WrapPanel Orientation="Horizontal" Width="250" Background="{x:Null}" VerticalAlignment="Top"></WrapPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
<Border Grid.Column="1" BorderBrush="Gainsboro" BorderThickness="5" Margin="10,60,10,10">
<Grid Name="grdPalletTab2" AllowDrop="True" Drop="Grid_Drop"/>
</Border>
</Grid>
</Border>
</Grid>
</TabItem>
the grid is formed through
PalletWindow.PalletWindow.SetPalletGrid(numRows, numColumns,ref grdPalletTab2);
whose code is:
public static bool SetPalletGrid(int numRows, int numColumns, ref Grid grd)
{
try
{
grd.Children.Clear();
grd.RowDefinitions.Clear();
grd.ColumnDefinitions.Clear();
grd.AllowDrop = true;
for (int row = 0; row < numRows; row++)
{
var rd = new RowDefinition();
rd.AllowDrop = true;
rd.Height = new GridLength(1.0, GridUnitType.Star);
grd.RowDefinitions.Add(rd);
}
for (int column = 0; column < numColumns; column++)
{
var cd = new ColumnDefinition();
cd.AllowDrop = true;
cd.Width = new GridLength(1.0, GridUnitType.Star);
grd.ColumnDefinitions.Add(cd);
}
for (int row = 0; row < numRows; row++)
{
for (int column = 0; column < numColumns; column++)
{
var borderImage = new Border();
borderImage.AllowDrop = true;
borderImage.BorderThickness = new Thickness(2);
borderImage.BorderBrush = new SolidColorBrush(Colors.Black);
borderImage.Name = "BRD_" + row + "_" + column;
borderImage.Effect = new DropShadowEffect
{
Color = new Color { R = 255, G = 255, B = 255 },
Direction = 320,
ShadowDepth = 5,
Opacity = 0.95
};
Grid.SetRow(borderImage, row);
Grid.SetColumn(borderImage, column);
grd.Children.Add(borderImage);
}
}
return true;
}
catch// (Exception exc)
{
return false;
}
}
thanks for any help
Patrick
To make d&d work you have to set the background of the target element (don't know why). In your case set borderImage = new SolidColorBrush(Colors.Transparent);
I built an messagebar, with an animated text,
see the .gif from the animation.
Like you can see the text "fly's" in the foreground and hides the placeholder. But I need the placeholder in the foreground.
My first idea was to change the region of the animation from
doubleAnimation.To = tbInfo.ActualWidth *-1;
to
doubleAnimation.To = boLogo.ActualWidth;
but the result looks like this: version with other animation area.
How can I set the placeholder in the foreground, so that the animation "fly's" behind it?
My XAML-Code
<Canvas x:Name="canMain" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Border x:Name="boLogo" Height="40" Background="Gray" Canvas.Left="0" Canvas.Top="-20">
<Button Content="Placeholder" Width="90" />
</Border>
<TextBlock x:Name="tbInfo" Visibility="Hidden" FontSize="32" FontWeight="Bold" Padding="5" HorizontalAlignment="Stretch" VerticalAlignment="Center"></TextBlock>
</Canvas>
and the code to show the window
public void ShowWindow(string str)
{
tbInfo.Text = str;
this.Height = 39;
this.Width = SystemParameters.WorkArea.Width;
this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
this.Show();
TextMarquee(20);
}
private void TextMarquee(int duration)
{
double height = canMain.ActualHeight - tbInfo.ActualHeight;
tbInfo.Margin = new Thickness(0, height / 2, 0, 0);
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = canMain.ActualWidth;
doubleAnimation.To = tbInfo.ActualWidth * -1;
doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(duration));
tbInfo.BeginAnimation(Canvas.LeftProperty, doubleAnimation);
tbInfo.Visibility = Visibility.Visible;
}
Use the Panel.ZIndex:
<Canvas x:Name="canMain" >
<Border x:Name="boLogo" Panel.ZIndex="2">
<Button Content="Placeholder" Width="90" />
</Border>
<TextBlock x:Name="tbInfo" Panel.ZIndex="1"></TextBlock>
</Canvas>
https://msdn.microsoft.com/de-de/library/system.windows.controls.panel.zindex%28v=vs.110%29.aspx
Try the Grid.ZIndex:
<Grid x:Name="canMain" >
<Border x:Name="boLogo" Grid.ZIndex="2">
<Button Content="Placeholder" />
</Border>
<TextBlock x:Name="tbInfo" Grid.ZIndex="1"/>
</Grid>
Being ZIndex = "2" the most visible layer.
I am trying to restrict the image movement placed inside a canvas on touch manipulation while translating, rotating and scaling(pinch to zoom).
I tried to implement manipulationcontainer property but it didn't give me the desired results.
Any help is appreciated!!!
XAMl Code-
<Canvas x:Name="mainCanvas" Grid.Column="1">
<Canvas.Background>
<ImageBrush x:Name="imgBg" ImageSource="/Images/Backgrounds/bg0.jpg"/>
</Canvas.Background>
<Image x:Name="imgTest" Source="/Images/Sample.jpg" ManipulationStarted="image_OnManipulationStarted" ManipulationDelta="image_OnManipulationDelta" Height="150" Width="190" Canvas.Top="80" Margin="12,0,0,0" Stretch="Fill">
<Image.RenderTransform>
<CompositeTransform />
</Image.RenderTransform>
</Image>
<Image x:Name="imgTest2" Source="/Images/Sample2.jpg" ManipulationStarted="image_OnManipulationStarted" ManipulationDelta="image_OnManipulationDelta" Height="150" Width="190" Canvas.Top="80" Canvas.Left="200" Margin="12,0,0,0" Stretch="Fill">
<Image.RenderTransform>
<CompositeTransform />
</Image.RenderTransform>
</Image>
<Image x:Name="imgTest3" Source="/Images/Sample3.jpg" ManipulationStarted="image_OnManipulationStarted" ManipulationDelta="image_OnManipulationDelta" Height="150" Width="190" Canvas.Top="240" Margin="12,0,0,0" Stretch="Fill">
<Image.RenderTransform>
<CompositeTransform />
</Image.RenderTransform>
</Image>
<Image x:Name="imgTest4" Source="/Images/Sample4.jpg" ManipulationStarted="image_OnManipulationStarted" ManipulationDelta="image_OnManipulationDelta" Height="150" Width="190" Canvas.Top="240" Canvas.Left="200" Margin="12,0,0,0" Stretch="Fill">
<Image.RenderTransform>
<CompositeTransform />
</Image.RenderTransform>
</Image>
</Canvas>
C# Code-
double _scaleX, _scaleY, _translationX, _translationY;
private void image_OnManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
// the user has started manipulating the screen, set starting points
var transform = (CompositeTransform)((System.Windows.FrameworkElement)(sender)).RenderTransform;
_scaleX = transform.ScaleX;
_scaleY = transform.ScaleY;
_translationX = transform.TranslateX;
_translationY = transform.TranslateY;
e.ManipulationContainer = mainCanvas;
e.Handled = true;
}
private void image_OnManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
var transform = (CompositeTransform)((FrameworkElement)(sender)).RenderTransform;
Image imgSender = sender as Image;
// pan
transform.TranslateX = _translationX + e.CumulativeManipulation.Translation.X;
transform.TranslateY = _translationY + e.CumulativeManipulation.Translation.Y;
if (e.PinchManipulation != null)
{
// zoom
transform.CenterX = e.PinchManipulation.Original.Center.X;
transform.CenterY = e.PinchManipulation.Original.Center.Y;
transform.ScaleX = _scaleX * e.PinchManipulation.CumulativeScale;
transform.ScaleY = _scaleY * e.PinchManipulation.CumulativeScale;
//rotate
transform.Rotation = angleBetween2Lines(e.PinchManipulation.Current, e.PinchManipulation.Original);
}
Point p = new Point(0, 0);
Rect containingRect = new Rect(p,((FrameworkElement)e.ManipulationContainer).RenderSize);
Rect shapeBounds = imgSender.RenderTransform.TransformBounds(new Rect(p,imgSender.RenderSize));
Point bound = new Point(shapeBounds.Top, shapeBounds.Bottom);
if (e.IsInertial && !containingRect.Contains(bound))
{
e.Complete();
}
e.Handled = true;
}
Keeping the parent canvas as a child of ScrollViewer worked for me.
This question already has an answer here:
Draw on image control in WPF
(1 answer)
Closed 9 years ago.
In C# with WPF, how do I draw an Image? I have tried searching online, but all the tutorials I seem to find deal with drawing a shape, or setting a background Image.
I am interested in trying to create a chess program. I have the board set as the background Image, but cannot figure out how to draw images for the pieces.
Ok, this is my take on a ChessBoard:
<Window x:Class="MiscSamples.ChessBoard"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MiscSamples"
Title="ChessBoard" Height="300" Width="300">
<Window.Resources>
<DataTemplate DataType="{x:Type local:ChessPiece}">
<Image Source="{Binding ImageSource}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<UniformGrid Rows="8" Columns="8" Opacity=".5">
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
<Rectangle Fill="Black"/>
<Rectangle Fill="White"/>
</UniformGrid>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid IsItemsHost="True">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding Row}"/>
<Setter Property="Grid.Column" Value="{Binding Column}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Window>
Code Behind:
using System.Linq;
using System.Windows;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace MiscSamples
{
public partial class ChessBoard : Window
{
public ObservableCollection<ChessPiece> Pieces { get; set; }
public ChessBoard()
{
Pieces = new ObservableCollection<ChessPiece>();
InitializeComponent();
DataContext = Pieces;
NewGame();
}
private void NewGame()
{
Pieces.Clear();
Pieces.Add(new ChessPiece() { Row = 0, Column = 0, Type = ChessPieceTypes.Tower, IsBlack = true});
Pieces.Add(new ChessPiece() { Row = 0, Column = 1, Type = ChessPieceTypes.Knight, IsBlack = true });
Pieces.Add(new ChessPiece() { Row = 0, Column = 2, Type = ChessPieceTypes.Bishop, IsBlack = true });
Pieces.Add(new ChessPiece() { Row = 0, Column = 3, Type = ChessPieceTypes.Queen, IsBlack = true });
Pieces.Add(new ChessPiece() { Row = 0, Column = 4, Type = ChessPieceTypes.King, IsBlack = true });
Pieces.Add(new ChessPiece() { Row = 0, Column = 5, Type = ChessPieceTypes.Bishop, IsBlack = true });
Pieces.Add(new ChessPiece() { Row = 0, Column = 6, Type = ChessPieceTypes.Knight, IsBlack = true });
Pieces.Add(new ChessPiece() { Row = 0, Column = 7, Type = ChessPieceTypes.Tower, IsBlack = true });
Enumerable.Range(0, 8).Select(x => new ChessPiece()
{
Row = 1,
Column = x,
IsBlack = true,
Type = ChessPieceTypes.Pawn
}).ToList().ForEach(Pieces.Add);
Pieces.Add(new ChessPiece() { Row = 7, Column = 0, Type = ChessPieceTypes.Tower, IsBlack = false });
Pieces.Add(new ChessPiece() { Row = 7, Column = 1, Type = ChessPieceTypes.Knight, IsBlack = false });
Pieces.Add(new ChessPiece() { Row = 7, Column = 2, Type = ChessPieceTypes.Bishop, IsBlack = false });
Pieces.Add(new ChessPiece() { Row = 7, Column = 3, Type = ChessPieceTypes.Queen, IsBlack = false });
Pieces.Add(new ChessPiece() { Row = 7, Column = 4, Type = ChessPieceTypes.King, IsBlack = false });
Pieces.Add(new ChessPiece() { Row = 7, Column = 5, Type = ChessPieceTypes.Bishop, IsBlack = false });
Pieces.Add(new ChessPiece() { Row = 7, Column = 6, Type = ChessPieceTypes.Knight, IsBlack = false });
Pieces.Add(new ChessPiece() { Row = 7, Column = 7, Type = ChessPieceTypes.Tower, IsBlack = false });
Enumerable.Range(0, 8).Select(x => new ChessPiece()
{
Row = 6,
Column = x,
IsBlack = false,
Type = ChessPieceTypes.Pawn
}).ToList().ForEach(Pieces.Add);
}
}
ViewModel:
public class ChessPiece: INotifyPropertyChanged
{
public bool IsBlack { get; set; }
public ChessPieceTypes Type { get; set; }
private int _row;
public int Row
{
get { return _row; }
set
{
_row = value;
OnPropertyChanged("Row");
}
}
private int _column;
public int Column
{
get { return _column; }
set
{
_column = value;
OnPropertyChanged("Column");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public string ImageSource
{
get { return "../ChessPieces/" + (IsBlack ? "Black" : "White") + Type.ToString() + ".png"; }
}
}
public enum ChessPieceTypes
{
Pawn,
Tower,
Knight,
Bishop,
Queen,
King,
}
}
This is what it looks like in my computer:
Please notice that I'm using pure XAML to create the UI. In no way Im creating nor manipulating UI elements in code. WPF doesn't need that, and it's also not recommended.
The recommended approach to WPF is to use MVVM and understand that UI is Not Data
You can copy and paste my code in a File -> New Project -> WPF Application and see the results for yourself. You will need the following project structure:
Also note that the Image files need to be set to Build Action: Resource.
Remember: This is the WPF approach to EVERYTHING. You rarely have to manipulate UI elements in code in WPF, or do things such as drawing or anything like that.
It depends on how you whould like to draw i usually work with bit drawing and here is the way i do it.
//Initialize image and stuff
int Width = 100;
int Height = 100;
int nStride = (Width * PixelFormats.Bgra32.BitsPerPixel + 7) / 8;
Int32Rect ImageDimentions = new Int32Rect(0, 0, Width, Height);
int[] ImageArr = new ImageArr[Height * nStride];
//Manually paint your image
for (int Y = 0; Y < Height; Y++)
{
for (int X = 0; X < Width; X++)
{
//X and Y means pixel(X,Y) in cartesian plane 1 quadrant mirrored around X axis
//Down is the Y from 0 to height, and right to left is X from 0 to width
int index = (Y * Width + X) * 4;
ImageArr[index + 0] = (byte)0; //Blue
ImageArr[index + 1] = (byte)0; //Green
ImageArr[index + 2] = (byte)0; //Red
ImageArr[index + 3] = (byte)255; //Alpha
}
}
//Push your data to a Bitmap
WriteableBitmap BmpToWriteOn = new WriteableBitmap(Width, Height, 96, 96, PixelFormats.Bgra32, null);
BmpToWriteOn.WritePixels(ImageDimentions, ImageArr, nStride, 0, 0);
//Push your bitmap to Xaml Image
YourXamlImage.Source = BmpToWriteOn;
For bitmaps, you can use BitmapImage:
http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapimage.aspx