WPFとC#を使用して最初のプログラムを作成しています。私のウィンドウには、単純なキャンバスコントロールが含まれています。
<StackPanel Height="311" HorizontalAlignment="Left" Name="PitchPanel" VerticalAlignment="Top" Width="503" Background="Black" x:FieldModifier="public"></StackPanel>
これは正常に機能し、Window.Loaded
イベントから。という名前のこのCanvasにアクセスできますPitchPanel
。
Game
ここで、次のように初期化されるというクラスを追加しました。
public Game(System.Windows.Window Window, System.Windows.Controls.Canvas Canvas)
{
this.Window = Window;
this.Canvas = Canvas;
this.GraphicsThread = new System.Threading.Thread(Draw);
this.GraphicsThread.SetApartmentState(System.Threading.ApartmentState.STA);
this.GraphicsThread.Priority = System.Threading.ThreadPriority.Highest;
this.GraphicsThread.Start();
//...
}
ご覧のとおり、。というスレッドがありますGraphicsThread
。これにより、現在のゲーム状態が次のように可能な限り高いレートで再描画されます。
private void Draw() //and calculate
{
//... (Calculation of player positions occurs here)
for (int i = 0; i < Players.Count; i++)
{
System.Windows.Shapes.Ellipse PlayerEllipse = new System.Windows.Shapes.Ellipse();
//... (Modifying the ellipse)
Window.Dispatcher.Invoke(new Action(
delegate()
{
this.Canvas.Children.Add(PlayerEllipse);
}));
}
}
しかし、ゲームインスタンスの作成時に渡されるメインウィンドウによって呼び出されるディスパッチャーを使用しましたが、未処理の例外が発生します。[System.Reflection.TargetInvocationException]
内部例外は、オブジェクトが別のスレッドによって所有されているため、オブジェクトにアクセスできないことを示しています(メインスレッド)。
ゲームは、アプリケーションのWindow_Loadedイベントで初期化されます。
GameInstance = new TeamBall.Game(this, PitchPanel);
これは、この回答で与えられたのと同じ原則だと思います。
では、なぜこれが機能しないのですか?別のスレッドからコントロールを呼び出す方法を知っている人はいますか?