私は現在 C# でアプリケーションを作成しており、外部の VB スクリプトが何らかの方法でアプリケーションの WPF ベースの GUI を操作できるようにしたいと考えています。これらのスクリプトは、非常に長時間実行し、実行中のスレッドを一時停止できるようにする必要があります (これは、実行時に VBScript がビューの内容を決定する小さなスライドショーのようなアプリケーションです)。これを実現するために、ScriptControl COM コンポーネントを参照し、クラスをComVisibleにしました。選択したスクリプトは、次のようにScriptingHostによって実行されます。
public void Run(Action callback)
{
var thread = new Thread(() =>
{
_ScriptControl.Run("Execute", new object[] { }); // _ScriptControl is the COM component
callback();
});
thread.Start();
}
アプリケーションで画像を表示するには、ビュー モデルで次のメソッドを使用します (VBScript から呼び出します)。
public void ShowPicture(string path)
{
BitmapImage bmImage = new BitmapImage();
bmImage.BeginInit();
bmImage.UriSource = new Uri(path, UriKind.Absolute);
bmImage.EndInit();
bmImage.Freeze();
_CurrentImage = bmImage;
RaisePropertyChanged("CurrentImage");
// System.Windows.Forms.Application.DoEvents();
}
プロパティCurrentImage
は、新しく作成された BitmapImage ( _CurrentImage
) を返し、ビューのイメージ コントロールにバインドされます。
スクリプト スレッドを一時停止するスクリプトを実行すると (ユーザーが画像を見る時間を与えるため) 、イベントが発生した後Thread.Sleep()
も画像コントロールはCurrentImage
プロパティを取得しますが、画像は表示されません。DoEvents
呼び出しまたはどこかを追加するとMessageBox.Show
、GUI が適切に更新されます。
ShowPicture
別のスレッドでメソッドを呼び出し、その後に a が続く画像を表示しようとしましたがThread.Sleep()
、これはうまく機能します (ScriptControl COM コンポーネントなし)。
ScriptControl COM コンポーネントは何らかの方法で UI スレッドを使用していますか (私は既に に設定AllowUI
していますfalse
)、それとも何か他の不可解な COM 処理が行われているのでしょうか?
スクリプト例:
Function Execute()
For Each picture In Source.GetPictures(False)
Canvas.ShowPicture(picture)
Host.Wait(5) ' Thread.Sleep(5000)
Next
End Function