在UWP App中实现可拆卸面板

时间:2017-12-03 06:57:43

标签: xaml uwp windows-runtime winrt-xaml windows-10-universal

我在网格中有一个Image,我通过将图像的源设置为WritableBitmap并更新位图来显示一些自定义内容。我想要做的是实现一个“分离”按钮,它将我的图像放在一个单独的窗口上,允许用户将其移动到不同的屏幕,调整大小等,独立于我的主应用程序窗口。如果新窗口关闭,我想把它带回原来的位置。当Image在新窗口中时,我想通过更新源位图(就像它在分离之前一样)用新内容不断更新它。

我最初认为我可以创建一个新窗口并“移动”我的Image控件,首先将其从原始父级中删除,然后将其作为子项添加到新窗口中的布局中。我使用下面的代码:

CoreApplicationView^ newCoreView = CoreApplication::CreateNewView();
int mainViewId = Windows::UI::ViewManagement::ApplicationView::GetApplicationViewIdForWindow(
    CoreApplication::MainView->CoreWindow);

uint indexOfObjectToDetach = -1;
bool found = originalGrid->Children->IndexOf(imageToMove, &indexOfObjectToDetach);
if(found)
{
    myGrid->Children->RemoveAt(indexOfObjectToDetach);
}

DispatchedHandler^ dispatchHandler = ref new DispatchedHandler([this, mainViewId]()
{
    newView_ = Windows::UI::ViewManagement::ApplicationView::GetForCurrentView();
    Windows::UI::Xaml::Controls::StackPanel^ newWindowGrid = ref new Windows::UI::Xaml::Controls::StackPanel();
    Window::Current->Content = newWindowGrid;
    Window::Current->Activate();

    newWindowGrid->Children->Append(imageToMove); // Add to new parent
});

create_task(newCoreView->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, dispatchHandler)).then([this, mainViewId]()
{
    auto a = newView_->Id;
    create_task(ApplicationViewSwitcher::TryShowAsStandaloneAsync(a, ViewSizePreference::Default, mainViewId, ViewSizePreference::Default));
});

但是,在我将Im​​age添加到其新父级的行中,我收到Interface was marshalled for a different thread错误。更多阅读,这是因为每个新窗口都在自己的线程中,我正在将一个对象移动到另一个线程。

我是UWP的新手,我不确定如何实现这种UI行为。如何在一个视图中访问/转移我的状态到另一个视图?

1 个答案:

答案 0 :(得分:1)

问题确实是UWP中的每个应用程序视图都有自己的线程和自己的UI调度程序。创建控件时,它与创建它的UI线程相关联,因此您无法将其放在另一个应用程序视图上。

解决方案是在新视图的UI线程中的Image旁边创建新的StackPanel。我并不真正使用C ++,但在C#中我会按如下方式实现它:

await newCoreView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        StackPanel panel = new StackPanel();
        Image image = new Image();
        panel.Children.Add( panel );
        image.Source = ...; //your source
        Window.Current.Content = frame;
        Window.Current.Activate();
        newViewId = ApplicationView.GetForCurrentView().Id;
    });

为了进一步说明 - 您可以安全地将正常数据类型“转移”到其他视图中,问题主要在于与UI相关的类型,如控件,页面等。