我正在尝试为Page
类编写一个扩展方法,该方法将返回一个用户控件,该控件是根Grid
的动态创建的子级。我遇到的问题是使用Content
类的Page
属性。
目的是返回控件以检查控件的属性,并且主要从主线程调用。
这是我正在尝试做的事情:
public static MyUserControl GetControlByTag(this Page page, int tag) {
//throws "marshalled from a different thread" exception
Grid rootGrid = page.Content as Grid;
if(rootGrid != null) {
var controls = rootGrid.Children.OfType<MyUserControl>();
foreach(MyUserControl control in controls)
{
if(control.Tag == tag) return control;
}
return null;
}
我已经尝试使用返回类型Task<Grid>
的辅助方法来获取对象,但是我找不到同步返回异步Task的方法,我似乎无法找到同步的方法从page.Dispatcher.RunAsync()
返回一个值。
这通常是XAML布局的样子:
<Page>
<Grid>
...
...
...
<MyUserControl/>
<MyUserControl/>
<MyUserControl/>
<Grid/>
</Page>
答案 0 :(得分:0)
我通过MSDN找到了解决方案:
public static MyUserControl GetControlByTag(this Page page, int tag) {
MyUserControl rtn = null;
page.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
Grid rootGrid = page.Content as Grid;
if(rootGrid != null) {
var controls = rootGrid.Children.OfType<MyUserControl>();
foreach(MyUserControl control in controls)
{
if(control.Tag == tag) rtn = control;
}
}
}).AsTask().Wait(); //Runs the dispatcher synchronously
return rtn;
}
编辑:但是,如果要在整个应用程序中使用它,请注意:您可能必须检查该方法是否已具有线程访问权限。我还没有找到一种优雅的方式来做到这一点,但它的基本知识看起来像这样:
public static MyUserControl GetControlByTag(this Page page, int tag) {
Grid rootGrid = page.Content as Grid;
if(page.Dispatcher.HasThreadAccess) {
//Code to run
}
else {
page.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
//Code to run
}).AsTask().Wait();
}
}