1.Canvas面板
using System;using System.Windows;using System.Windows.Controls;using System.Windows.Media;using System.Windows.Input;using System.Windows.Shapes;namespace LY.PaintTheButton{ public class PaintTheButton:Window { [STAThread] public static void Main() { new Application().Run(new PaintTheButton()); } public PaintTheButton() { Title = "Paint The Button"; Button btn = new Button(); btn.HorizontalAlignment = HorizontalAlignment.Center; btn.VerticalAlignment = VerticalAlignment.Center; Content = btn; Canvas canv = new Canvas(); canv.Width = 144; canv.Height = 144; btn.Content = canv; Rectangle rect = new Rectangle(); rect.Width = canv.Width; rect.Height = canv.Height; //使矩形的角变圆 rect.RadiusX = 24; rect.RadiusY = 24; rect.Fill = Brushes.Blue; canv.Children.Add(rect); //根据坐标位置放置控件 Canvas.SetLeft(rect, 0); Canvas.SetTop(rect, 0); Polygon poly = new Polygon(); poly.Fill = Brushes.Yellow; //颜色填充规则 poly.FillRule = FillRule.Nonzero; //poly.Points=new PointCollection(); for (int i = 0; i < 5; i++) { double angle = i * 4 * Math.PI / 5; Point pt = new Point(48 * Math.Sin(angle), -48 * Math.Cos(angle)); poly.Points.Add(pt); } canv.Children.Add(poly); Canvas.SetLeft(poly, canv.Width / 2); Canvas.SetTop(poly, canv.Height / 2); } }}
Canvas面板是根据坐标放置控件。
2.UniformGrid面板
using System;using System.Windows;using System.Windows.Controls;using System.Windows.Controls.Primitives;using System.Windows.Input;using System.Windows.Media;using System.Windows.Threading;namespace LY.Puzzle{ public class PlayPuzzle : Window { int xEmpty, yEmpty, iCounter; UniformGrid unigrid; Random rand; [STAThread] public static void Main() { new Application().Run(new PlayPuzzle()); } public PlayPuzzle() { Title = "LY的小游戏"; SizeToContent = SizeToContent.WidthAndHeight; ResizeMode = ResizeMode.CanMinimize; Background = SystemColors.ControlBrush; //加入一个Stack面板 StackPanel stack = new StackPanel(); Content = stack; //加入按钮 Button btn = new Button(); btn.Content = "打乱(_S)"; btn.HorizontalAlignment = HorizontalAlignment.Center; btn.Margin = new Thickness(10); btn.Click += btn_Click; stack.Children.Add(btn); //加入边框 Border bord = new Border(); bord.BorderThickness = new Thickness(1); bord.BorderBrush = SystemColors.ControlDarkDarkBrush; stack.Children.Add(bord); //加入UniformGrid面板 unigrid = new UniformGrid(); unigrid.Rows = 4; unigrid.Columns = 4; bord.Child = unigrid; for (int i = 0; i < 15; i++) { Tile tile = new Tile(); tile.Text = (i + 1).ToString(); tile.MouseDown += tile_MouseDown; unigrid.Children.Add(tile); } unigrid.Children.Add(new Empty()); xEmpty = 3; yEmpty = 3; } private void btn_Click(object sender, RoutedEventArgs e) { rand = new Random(); iCounter = 16 * 4 * 4; DispatcherTimer tim = new DispatcherTimer(); tim.Interval = TimeSpan.FromMilliseconds(10); tim.Tick += tim_Tick; tim.Start(); } void tim_Tick(object sender, EventArgs e) { for (int i = 0; i < 5; i++) { MoveTile(xEmpty, yEmpty + rand.Next(3) - 1); MoveTile(xEmpty + rand.Next(3) - 1, yEmpty); } iCounter--; if (iCounter == 0) (sender as DispatcherTimer).Stop(); } private void tile_MouseDown(object sender, MouseButtonEventArgs e) { Tile tile = sender as Tile; int yTile = unigrid.Children.IndexOf(tile) / 4; int xTile = unigrid.Children.IndexOf(tile) % 4; //可以一次移动多个tile,所以用while循环 if (xTile == xEmpty) while (yTile != yEmpty) MoveTile(xTile, yEmpty + (yTile - yEmpty) / Math.Abs(yTile - yEmpty)); if (yTile == yEmpty) while (xTile != xEmpty) MoveTile(xEmpty + (xTile - xEmpty) / Math.Abs(xTile - xEmpty), yTile); } private void MoveTile(int xTile, int yTile) { //为tim_Tick事件剔除无用值 if ((xTile == xEmpty && yTile == yEmpty) || xTile < 0 || xTile > 3 || yTile < 0 || yTile > 3) return; int iTile = yTile * 4 + xTile; int iEmpty = yEmpty * 4 + xEmpty; UIElement elTile = unigrid.Children[iTile]; UIElement elEmpty = unigrid.Children[iEmpty]; unigrid.Children.Remove(elTile); unigrid.Children.Insert(iEmpty, elTile); unigrid.Children.Remove(elEmpty); unigrid.Children.Insert(iTile, elEmpty); xEmpty = xTile; yEmpty = yTile; } protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); switch (e.Key) { case Key.Right: MoveTile(xEmpty - 1, yEmpty); break; case Key.Left: MoveTile(xEmpty + 1, yEmpty); break; case Key.Down: MoveTile(xEmpty, yEmpty - 1); break; case Key.Up: MoveTile(xEmpty, yEmpty + 1); break; } } }}
using System;using System.Windows;using System.Windows.Controls;using System.Windows.Input;using System.Windows.Media;using System.Windows.Shapes;namespace LY.Puzzle{ public class Tile : Canvas { const int Bord = 6; const int Size = 64; TextBlock txtblk; public Tile() { Width = Size; Height = Size; //左上多边形 Polygon poly = new Polygon(); poly.Points = new PointCollection(new Point[]{ new Point(0,0),new Point(Size,0),new Point(Size-Bord,Bord), new Point(Bord,Bord),new Point(Bord,Size-Bord), new Point(0,Size)}); poly.Fill = SystemColors.ControlLightLightBrush; Children.Add(poly); //poly本身带着坐标信息,因此不用再设定在面板中的位置 //Canvas.SetLeft(poly, 0); //Canvas.SetTop(poly, 0); //右下多边形 poly = new Polygon(); poly.Points = new PointCollection(new Point[]{ new Point(Size,Size),new Point(0,Size),new Point(Bord,Size-Bord), new Point(Size-Bord,Size-Bord),new Point(Size-Bord,Bord), new Point(Size,0)}); poly.Fill = SystemColors.ControlDarkBrush; Children.Add(poly); //很多图形对象本身带着坐标信息 //Canvas.SetRight(poly, 0); //Canvas.SetBottom(poly, 0); //在元素周围绘制边框或背景 Border border = new Border(); border.Width = Size - 2 * Bord; border.Height = Size - 2 * Bord; //border.BorderThickness = new Thickness(6); border.Background = SystemColors.ControlBrush; Children.Add(border); //这里以下两种方式都可以 SetLeft(border, Bord); Canvas.SetTop(border, Bord); //中间放上TextBlock控件 txtblk = new TextBlock(); txtblk.FontSize = 32d; txtblk.Foreground = SystemColors.ControlTextBrush; txtblk.HorizontalAlignment = HorizontalAlignment.Center; txtblk.VerticalAlignment = VerticalAlignment.Center; border.Child = txtblk; } public string Text { get { return txtblk.Text; } set { txtblk.Text = value; } } } //空白格子类 class Empty : FrameworkElement { }}
UniformGrid面板类似于Grid面板,但它是固定行列大小的,用Rows、Columns直接指定行数和列数即可。