2012-03-19 17 views
2

私はカードゲームになるVB Silverlightアプリケーションを持っています。私は個々のカード(プログラムで作成し、Silverlightの "Image"コントロールとして独自の "CardImage"クラスでラップ)を手に入れようとしていました。私は、マウスがそれらの上にあるときにそれらを "ポップアップ"のようなものにして、マウスが離れるときに戻ってくるようにします。シルバーライトで無効なクロススレッド例外

本質的に、Image.Margin.Topをマウスセンターの5ピクセル上に移動し、マウス離脱イベントの5ピクセル下に移動します。

スレッド間のアクセスが無効であるという「処理されない例外」が発生していて、宿題をしていて、UIスレッドとワーカースレッドなどについて学んだことがあります。また、「begininvoke "より安全なスレッドになるために練習すること。

ここに問題があります:例外はまだ起こっています。

は、ここに私のコードです:

Public Class CardImage 

Public Disp As Dispatcher = Deployment.Current.Dispatcher 
Public WithEvents Image As New Image 

Private Sub MouseEnter(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Image.MouseEnter 
    Try 
     Invoke(Sub() Image.Margin = New Thickness(Image.Margin.Left, Image.Margin.Top - 5, 0, 0)) 
    Catch ex As Exception 

    End Try 
End Sub 
Private Sub MouseLeave(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Image.MouseLeave 
    Try 
     Invoke(Sub() Image.Margin = New Thickness(Image.Margin.Left, Image.Margin.Top + 5, 0, 0)) 
    Catch ex As Exception 

    End Try 
End Sub 

Private Sub Invoke(ByVal act As Action) 
    If Disp.CheckAccess Then 
     act.Invoke() 
    Else 
     Disp.BeginInvoke(act) 
    End If 
End Sub 
End Class 

私は(全体で13枚のカードの「手」など)が表示されているすべてのカード間で非常に高速にマウスを移動すると、例外がスローされます。プレイヤーはこの種のことをやり遂げる可能性があることを念頭に置いてください... ADHDを持つユーザーの中には、カードが波及して「波をやりたい」と決めているため、アプリがクラッシュしないようにしたいと思っています。他の人が自分のカードをプレイするのを待っている間に。

私のUIスレッドがイメージマージンを更新しているスレッドをまだ使用していない理由についてのヒントはありますか?

+0

をFYI:私を –

+0

私の答えは間違っていたと思うあなたのメソッドはイベントハンドラから来ているので、すでにUIスレッドにあると思うだろうあなたはプログラムでCardImageインスタンスを別のスレッドに作成していますか? – Kratz

+0

@Kratzカードイメージは、メインのSilverlightページ上でボタンクリックイベントが発生した結果として作成されています。ボタン(単に新しいテストハンドを「扱う」ボタン)は、52個のCardImageオブジェクトをすべて作成し、配置します。だからあなたはそれがすべてUIスレッド上にあると思うでしょう。 –

答えて

0

「イメージ」は、CardImageを作成するスレッドのコンテキストで作成されます。それは、UIスレッドが、ワーカースレッドではない場合、あなたはマウスイベントを派遣どこに(UIスレッドからアクセスすることはできません

は、UIスレッドでそれを作成します。

Public WithEvents Image As Image 

Public Sub New() 

    Image = Invoke(Function() 
         return New Image 
        End Function) 

End Sub 

Private Function Invoke(ByVal procedure As Func(of System.Windows.Controls)) 

    If Disp.CheckAccess Then 
     return procedure.Invoke() 
    Else 
     return Disp.Invoke(procedure) 
    End If 

End Function 
関連する問題