2

Windows Phone アプリケーション (Silverlight) のアセンブリ (WindowsPhoneClassLibrary または PortableClassLibrary) を作成しているとします。

Application.Current.RootVisualnullではない瞬間を自動的に検出/登録/サブスクライブする方法はありますか?

私の現在の(例外のために機能していない)アプローチは、次の考えにあります。

var rootVisualTask = new TaskCompletionSource<UIElement>();
var application = Application.Current;
TaskEx.Run(() =>
{
    while (application.RootVisual == null)
        Thread.Sleep(1);
    rootVisualTask.TrySetResult(application.RootVisual);
});
var rootVisual = await rootVisualTask.Task;

編集

私のアセンブリが通常どのように初期化されるかを説明する McGarnagle への回答。

App.xaml.cs で:

static readonly PhoneApplicationFrame RootFrame = new PhoneApplicationFrame();
public App()
{
    InitializeComponent();
    RootFrame.Navigated += RootFrame_Navigated;
}
void RootFrame_Navigated(object sender, NavigationEventArgs e)
{
    RootVisual = RootFrame;
    RootFrame.Navigated -= RootFrame_Navigated;
}
void Application_Launching(object sender, LaunchingEventArgs e)
{
    MyPlugin.Start();
}
void Application_Activated(object sender, ActivatedEventArgs e)
{
    MyPlugin.Start();
}

物事は次の順序で起こります。

  1. Application.Startup(未使用)
  2. Application.Launching(プラグイン起動)
  3. RootFrame.Navigated(RootVisual は設定されていますが、RootFrame はプライベートです)

MyPlugin.HeyRootVisualIsSetAndNowYouCanUseIt()後で手動で挿入する必要がありましたRootVisual = ...が、それを避けようとしていました。

編集

Obj-C とは異なり、KVO は所有していないフィールド/プロパティには実装できません。つまり、おそらく誰もより良い解決策を見つけられないでしょう。

4

1 に答える 1

0

何時間も実験した後、これが機能することがわかりました:

var dispatcher = Deployment.Current.Dispatcher;
var application = Application.Current;
UIElement rootVisual = null;
while (rootVisual == null)
{
    var taskCompletionSource = new TaskCompletionSource<UIElement>();
    dispatcher.BeginInvoke(() =>
        taskCompletionSource.TrySetResult(application.RootVisual));
    rootVisual = await taskCompletionSource.Task;
}

私の質問のfrom the loop は、例外がスローされるのを避けるためにへThread.Sleep(1);の呼び出しに置き換えられます。Deployment.Current.Dispatcher.BeginInvoke()

于 2014-07-11T09:22:12.617 に答える