首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 組合控件實戰:中國象棋聯機對戰完整實作

     編輯:關於.NET

組合控件是 WPF 自訂控件的主流形式:以現有控件組合、樣式模板、視覺樹操作構建複雜 UI。本文以「中國象棋聯機對戰」為例,完整展示從棋盤繪製、棋子拖曳動畫、擊測選取、網路通訊到 MVVM 視窗關閉通知的工程級實作。

一、視覺層架構:DrawingVisual + 視覺樹

棋盤背景使用 DrawingVisual 繪製,棋子為獨立 UIElement 加入視覺樹:

// 建立棋盤視覺資料
var boardVisual = new DrawingVisual();
using (var dc = boardVisual.RenderOpen()) { DrawBoard(dc); }

// 覆寫視覺樹介面
protected override int VisualChildrenCount => 1 + Chessmen.Count; // 棋盤 + 棋子
protected override Visual GetVisualChild(int index) 
    => index == 0 ? boardVisual : Chessmen[index - 1];

MeasureOverride/ArrangeOverride 負責棋子佈局:

protected override Size MeasureOverride(Size available)
{
    foreach (var c in Chessmen) c.Measure(available);
    return new Size(CellWidth * 10, CellWidth * 11);
}

protected override Size ArrangeOverride(Size finalSize)
{
    foreach (var c in Chessmen)
        c.Arrange(new Rect(
            new Point(c.Location.X * CellWidth - c.DesiredSize.Width/2 + CellWidth,
                      c.Location.Y * CellWidth - c.DesiredSize.Height/2 + CellWidth),
            c.DesiredSize));
    return DesiredSize;
}

二、邏輯樹與屬性繼承

棋子繼承棋盤 FontFamily 等屬性,利用 DependencyProperty.AddOwner + FrameworkPropertyMetadataOptions.Inherits:

// 棋盤註冊
public static readonly DependencyProperty FontFamilyProperty =
    DependencyProperty.Register("FontFamily", ..., 
        new FrameworkPropertyMetadata(SystemFonts.MessageFontFamily, FrameworkPropertyMetadataOptions.Inherits));

// 棋子接管
public static readonly DependencyProperty FontFamilyProperty = 
    ChineseChessboard.FontFamilyProperty.AddOwner(typeof(ChessmanControl), ...);

三、擊測與拖曳動畫

  1. OnMouseLeftButtonDown:VisualTreeHelper.HitTest 取得棋子。
  2. 建立 TranslateTransform 套用至棋子 RenderTransform。
  3. 雙向 DoubleAnimation(X/Y)移動至目標格,FillBehavior.Stop 避免動畫結束殘留。
  4. 動畫完成事件中:清除 RenderTransform、更新棋子集合、呼叫 InvalidateArrange() 觸發實際佈局。

四、繪圖技巧

  • 棋盤立體感:雙色筆刷繪製網格線(深色上/左,淺色下/右)。
  • 對稱繪製:只畫第一象限,透過 ScaleTransform(-1,1)、ScaleTransform(1,-1)、ScaleTransform(-1,-1) 鏡像得到四象限。
  • 楚河/漢界垂直文字:FormattedText.MaxTextWidth = FontSize 擠壓換行,旋轉時修正長方形邊界偏移。
  • 背景圖片:BitmapImage + pack://application:,,,/Assembly;component/Images/xxx.jpg + Freeze() 提升跨執行緒效能。

五、動畫提醒機制

DispatcherTimer 定時觸發,CompositionTarget.Rendering 逐幀切換 Opacity 閃爍最後移動棋子,超時或換方自動停止。

六、UDP 聯機通訊

  • 協議:UDP 廣播尋找主機 → 主機回應 → 建立連線 → 走棋傳送座標。
  • 廣播發送:Socket.SendTo 目標 IPAddress.Broadcast。
  • 監聽埠:UdpClient + ReuseAddress 綁定,背景執行緒 Receive 迴圈。
  • 埠衝突處理:從 2000 起遞增嘗試 Bind 直到成功(可改良為 Port 0 自動分配)。
  • 序列化:自訂 Serialization/Deserialization,資料類別標記 [Serializable]。

七、MVVM 視窗關閉通知

問題:View 事件(Closing)如何綁定 ViewModel 命令?

解法:附加屬性 WindowRegionMetadata.BeforeClose 綁定 VM PersistAction,App.OnStartup 改用 WindowRegionBehavior.CreateWindow 建立視窗並注入 DataContext。

八、專案結構與原始碼

文章附上完整原始碼下載,包含:ChineseChessboard、ChessmanControl、UDPClass、WindowRegionBehavior、View/ViewModel、Shell 視窗等,可直接編譯運行體驗雙人聯機對戰。

總結

組合控件開發核心在於:視覺樹承載繪圖、邏輯樹傳遞屬性、擊測實現互動、動畫豐富體驗、網路實現聯機、MVVM 解耦業務。象棋專案雖簡單,但涵蓋 WPF 控件開發所有關鍵技術點,是絕佳的進階練習題材。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved