2010-03-18 19 views
3

看着Jeff Van Gogh's blog上的JavaScript演示的反應式擴展,我想我會嘗試在C#/ Winforms中,但它似乎並沒有工作得很好。時間飛得像WinForms中的箭頭演示

我只是把這個變成一種形式的(安裝並引用與RX框架)的構造:

Observable.Context = SynchronizationContext.Current; 
var mousemove = Observable.FromEvent<MouseEventArgs>(this, "MouseMove"); 
var message = "Time flies like an arrow".ToCharArray(); 

for(int i = 0; i < message.Length; i++) 
{ 
    var l = new Label() 
      { 
       Text = message[i].ToString(), 
       AutoSize = true, 
       TextAlign = ContentAlignment.MiddleCenter 
      }; 
    int closure = i; 
    mousemove 
     .Delay(closure * 150) 
     .Subscribe(e => 
      { 
       l.Left = e.EventArgs.X + closure * 15 + 10; 
       l.Top = e.EventArgs.Y; 
       //Debug.WriteLine(l.Text); 
      }); 
    Controls.Add(l); 
} 

當我移動鼠標,字母似乎隨機爲了得到感動,如果我取消了對Debug線的註釋,我看到了同一封信的多個事件...

任何想法?我嘗試過Throttle,但它似乎沒有任何區別。我只是要求太多的WinForms來移動所有這些標籤?

(交叉貼在Rx Forum

+1

你試過WPF ? – jrista 2010-03-18 06:38:38

+0

@jrista:尚未 – Benjol 2010-03-18 08:59:59

回答

2

回答交叉從Rx Forum貼後背(如果作者是在這裏,想聲稱它,那也沒關係由我):

問題1:你是使用舊的位。 Observable.Context在4個版本之前就不復存在了。 問題2:Javascript沒有線程的概念,而Rx喜歡把東西放在其他線程上給你。

所以,採用最新位,該解決方案看起來是這樣的:

void Form1_Load(object sender, EventArgs e) 
{ 
    Reactive("Time flies like an arrow"); 
} 

private void Reactive(string msg) 
{ 
    var mousemove = Observable.FromEvent<MouseEventArgs>(this, "MouseMove"); 
    var message = msg.ToCharArray(); 

    for(int i = 0; i < message.Length; i++) 
    { 
     var l = new Label() 
     { 
      Text = message[i].ToString(), 
      AutoSize = true, 
      TextAlign = ContentAlignment.MiddleCenter 
     }; 
     int closure = i; 
     mousemove 
      .Delay(TimeSpan.FromSeconds(0.07 * i), Scheduler.Dispatcher) 
      .Subscribe(e => 
      { 
       l.Left = e.EventArgs.X + closure * 12 - 5; 
       l.Top = e.EventArgs.Y + 15; 
      }); 
     Controls.Add(l); 
    } 
} 

通知的ObserveOnDispatcher和SubscribeOnDispatcher。這使我們接近Javascript版本,但線程再次成爲這裏真正的問題。

UPDATE,在上面的代碼從傑夫·梵高補充修正


只是爲了好玩,這裏是同樣的事情隱隱約約呈現不接收:

private void Unreactive(string msg) 
{ 
    var message = msg.ToCharArray(); 

    for(int i = 0; i < message.Length; i++) 
    { 
     var l = new Label() 
     { 
      Text = message[i].ToString(), 
      AutoSize = true, 
      TextAlign = ContentAlignment.MiddleCenter 
     }; 
     Controls.Add(l); 
     int closure = i; 
     this.MouseMove += (s, e) => LabelDelayMove(closure, e, l); 
    } 
} 

private void LabelDelayMove(int i, MouseEventArgs e, Label l) 
{ 
    Point p = new Point(e.X + i * 12 - 5, e.Y - 15); 
    var timer = new System.Threading.Timer((_) => LabelMove(l, p), null, i * 70, System.Threading.Timeout.Infinite); 
} 

private void LabelMove(Label l, Point location) 
{ 
    this.BeginInvoke(new Action(() => l.Location = location)); 
} 
+0

鏈接到原始帖子?啊,我在你的問題中看到它,但不是這個答案。 – 2010-03-18 14:15:34

+0

@理查德,是的,我已經添加了一個問題的鏈接,但不能爲我的生活看到哪裏可能有一個鏈接到答案。他們真的應該放棄他們的論壇,來這裏參加派對! – Benjol 2010-03-18 14:56:42