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

IronRuby 與 WPF 互操作實戰:從動態語言特性到 XAML 解析與 CLR 繼承

     編輯:關於.NET

WPF 基礎回顧

WPF 為 .NET Framework 圖形子系統,支援富媒體、動畫、資料視覺化。本文以類比鐘面應用展示 IronRuby 與 WPF 深度整合。

完整時鐘範例 (IronRuby)

require 'WindowsBase'
require 'PresentationFramework'
require 'PresentationCore'
require 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

class Clock
  CLOCK_WIDTH = 150; CLOCK_HEIGHT = 150
  LABEL_HEIGHT = CLOCK_HEIGHT / 7; LABEL_WIDTH = CLOCK_WIDTH / 7
  RADIUS = CLOCK_WIDTH / 2; RADS = Math::PI / 180
  MIN_LOCATIONS = {}; HOUR_LOCATIONS = {}

  def run!
    plot_locations
    @window = System::Windows::Window.new
    @window.background = System::Windows::Media::Brushes.LightGray
    @window.width = CLOCK_WIDTH * 2; @window.height = CLOCK_HEIGHT * 2
    @window.resize_mode = System::Windows::ResizeMode.NoResize

    @canvas = System::Windows::Controls::Canvas.new
    @canvas.width = CLOCK_WIDTH; @canvas.height = CLOCK_HEIGHT

    @minute_hand = System::Windows::Shapes::Line.new
    @minute_hand.stroke = System::Windows::Media::Brushes.Black
    @minute_hand.stroke_thickness = 1
    @minute_hand.x1 = CLOCK_WIDTH / 2; @minute_hand.y1 = CLOCK_HEIGHT / 2

    @hour_hand = System::Windows::Shapes::Line.new
    @hour_hand.stroke = System::Windows::Media::Brushes.Black
    @hour_hand.stroke_thickness = 3
    @hour_hand.x1 = CLOCK_WIDTH / 2; @hour_hand.y1 = CLOCK_HEIGHT / 2

    @canvas.children.add(@minute_hand)
    @canvas.children.add(@hour_hand)

    plot_face; plot_labels; plot_hands

    @window.content = @canvas
    System::Windows::Application.new.run(@window)
  end

  def plot_locations
    (0..60).each do |i|
      a = i * 6
      x = (RADIUS * Math.sin(a * RADS)).to_i + CLOCK_WIDTH / 2
      y = CLOCK_HEIGHT / 2 - (RADIUS * Math.cos(a * RADS)).to_i
      coords = [x, y]
      HOUR_LOCATIONS[i/5] = coords if i % 5 == 0
      MIN_LOCATIONS[i] = coords
    end
  end

  def plot_face
    extra_x = CLOCK_WIDTH * 0.15; extra_y = CLOCK_HEIGHT * 0.15
    face = System::Windows::Shapes::Ellipse.new
    face.fill = System::Windows::Media::Brushes.White
    face.width = CLOCK_WIDTH + extra_x; face.height = CLOCK_HEIGHT + extra_y
    face.margin = System::Windows::Thickness.new(-extra_x/2, -extra_y/2, 0, 0)
    face.stroke = System::Windows::Media::Brushes.Gray; face.stroke_thickness = 1
    System::Windows::Controls::Canvas.set_z_index(face, -1)
    @canvas.children.add(face)
  end

  def plot_labels
    HOUR_LOCATIONS.each_pair do |p, coords|
      next if p == 0
      lbl = System::Windows::Controls::Label.new
      lbl.horizontal_content_alignment = System::Windows::HorizontalAlignment.Center
      lbl.width = LABEL_WIDTH; lbl.height = LABEL_HEIGHT
      lbl.content = p.to_s
      lbl.margin = System::Windows::Thickness.new(coords[0] - LABEL_WIDTH/2, coords[1] - LABEL_HEIGHT/2, 0, 0)
      lbl.padding = System::Windows::Thickness.new(0,0,0,0)
      @canvas.children.add(lbl)
    end
  end

  def plot_hands
    time = Time.now
    hours = time.hour; minutes = time.min
    return if @minutes && minutes == @minutes

    @hours = hours >= 12 ? hours - 12 : hours
    @minutes = minutes == 0 ? 60 : minutes

    @minute_hand.dispatcher.begin_invoke(
      System::Windows::Threading::DispatcherPriority.Render,
      System::Action.new {
        @minute_hand.x2 = MIN_LOCATIONS[@minutes][0]
        @minute_hand.y2 = MIN_LOCATIONS[@minutes][1]
        @hour_hand.x2 = HOUR_LOCATIONS[@hours][0]
        @hour_hand.y2 = HOUR_LOCATIONS[@hours][1]
      })
  end
end

clock = Clock.new
timer = System::Timers::Timer.new
timer.interval = 1000
timer.elapsed { clock.plot_hands }
timer.enabled = true
clock.run!

關鍵互操作亮點

  • 無縫實例化:Ruby .new 直接建構 CLR 物件。
  • 命名慣例自動轉換:CLR PascalCase → Ruby snake_case (如 set_z_index)。
  • 事件訂閱優雅:timer.elapsed { clock.plot_hands } 對應 timer.Elapsed += ...,支援 method(:tick)、proc、lambda 多重訂閱。
  • XAML 解析:XamlReader.parse(File.read('xaml')) 直接建構物件樹,find_name 取得命名元素。
  • 繼承 CLR 類別:class Programmer < MyClassLibrary::Person 並擴充方法。
  • 命名空間簡化:include System::Windows::Shapes 或 WinForms = System::Windows::Forms 別名。

結語

IronRuby 賦予 .NET 動態語言表達力,配合 WPF 圖形能力,極適合資料視覺化快速原型。雖專案已停更,但其互操作設計思想仍具參考價值。

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