C++ 当 //用户正在执行拖动操作。 e、 AcceptedOperation(Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy); } void MainPage::OnListViewDrop(Windows::Foundation::IInspectable常量和目标,Windows::UI::Xaml::DragEventArgs常量和e) { //使用从中拖动的数据更新目标ListView //源列表视图。 auto p=target。请按()进行尝试; auto x=e.DataView().GetTextAsync();//**此行在删除时触发异常。 } }
在开始拖动之前,在源C++ 当 //用户正在执行拖动操作。 e、 AcceptedOperation(Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy); } void MainPage::OnListViewDrop(Windows::Foundation::IInspectable常量和目标,Windows::UI::Xaml::DragEventArgs常量和e) { //使用从中拖动的数据更新目标ListView //源列表视图。 auto p=target。请按()进行尝试; auto x=e.DataView().GetTextAsync();//**此行在删除时触发异常。 } },c++,xaml,uwp,drag-and-drop,c++-winrt,C++,Xaml,Uwp,Drag And Drop,C++ Winrt,在开始拖动之前,在源列表视图中选择项目的应用程序屏幕截图如下所示。源ListView控件位于左侧,目标ListView控件位于右侧。 附录:参考和文件 其中包含指向此示例项目的链接,该示例项目似乎正在使用C++/CX,其中包含一个有用的示例。出现异常的原因是由于误用了GetTextAsync()方法,该方法是一种异步方法,需要使用线程、任务、协同程序或其他一些并发功能 我找到了示例源代码,它提供了关于我做错了什么的提示。另见 为纠正问题所做更改概述 我决定与GetTextAsync()一起使
列表视图
中选择项目的应用程序屏幕截图如下所示。源ListView
控件位于左侧,目标ListView
控件位于右侧。
附录:参考和文件
其中包含指向此示例项目的链接,该示例项目似乎正在使用C++/CX,其中包含一个有用的示例。出现异常的原因是由于误用了
GetTextAsync()
方法,该方法是一种异步方法,需要使用线程、任务、协同程序或其他一些并发功能
我找到了示例源代码,它提供了关于我做错了什么的提示。另见
为纠正问题所做更改概述
我决定与GetTextAsync()
一起使用协同程序,因为我使用的是Visual Studio 2017社区版的最新版本。为此,需要将方法返回类型从void
更改为winrt::Windows::Foundation::iasyncation
,同时对解决方案属性进行一些更改,并添加一些include文件,以允许正确编译和运行协程更改
请参阅有关几种不同并发方法的答案和注释,以及Visual Studio 2017解决方案属性更改,以使用协同路由和co_wait
操作符
在MainPage.cpp的顶部,我添加了以下两个include指令:
#include <experimental\resumable>
#include <pplawait.h>
最后,我重写了方法OnListViewDrop()
,以如下方式使用协同程序(还要求更改类声明中声明的返回类型以与新的返回类型一致):
winrt::Windows::Foundation::IAsyncAction主页::OnListViewDrop(Windows::Foundation::IInspectable const&target,Windows::UI::Xaml::DragEventArgs const&e)
{
//使用从中拖动的数据更新目标ListView
//源ListView。方法GetTextAsync()是一个异步方法,因此
//我们正在使用协程来获得操作的结果。
//在执行co_wait之前,我们需要捕获目标ListView
//在局部变量中,以便我们知道要更新哪个ListView。
auto p=target。请按()进行尝试;
//执行GetTextAsync()并使用协同例程获得结果。
auto ss=co_wait e.DataView().GetTextAsync();
//更新最初触发此处理程序的ListView控件。
p、 Items().追加(框_值(ss));
}
auto x = e.DataView().GetTextAsync();
{m_handle={m_value=0x05550330 L"DataPackage does not contain the specified format. Verify its presence using DataPackageView.Contains or DataPackageView.AvailableFormats." } }
App::App()
{
InitializeComponent();
DataSource::InitializeDataBase();
Suspending({ this, &App::OnSuspending });
// … other code
#include "winrt/Windows.ApplicationModel.DataTransfer.h" // ADD_TO: need to add to allow use of drag and drop in MainPage.cpp
<Page
x:Class="TouchExperiment_01.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TouchExperiment_01"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Width="1130" Margin="0,0,0,0">
<ListView x:Name="myList" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="300" SelectionChanged="OnSelectionChanged"
CanDragItems="True" DragItemsStarting="OnListViewDragItemsStarting" BorderBrush="AliceBlue" BorderThickness="3">
</ListView>
<TextBlock x:Name="myTextBlock" Height="200" Width="200" Text="this is temp text to replace." TextWrapping="WrapWholeWords" Margin="5"/>
<ListView x:Name="myList2" HorizontalAlignment="Right" Height="100" VerticalAlignment="Top" Width="300" SelectionChanged="OnSelectionChanged" AllowDrop="True"
DragOver="OnListViewDragOver" Drop="OnListViewDrop" BorderBrush="DarkGreen" BorderThickness="5">
</ListView>
</StackPanel>
</Page>
#pragma once
class DataSource
{
public:
DataSource();
~DataSource();
static int InitializeDataBase();
struct DataSourceType
{
std::wstring name;
std::wstring description;
};
static std::vector<DataSourceType> myDataBase;
}
;
int DataSource::InitializeDataBase()
{
myDataBase.clear();
for (int i = 0; i < 50; i++) {
DataSourceType x;
wchar_t buffer[256] = { 0 };
swprintf_s(buffer, 255, L"Name for %d Item", i);
x.name = buffer;
swprintf_s(buffer, 255, L"Description %d. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.", i);
x.description = buffer;
myDataBase.push_back(x);
}
return 0;
}
#include "pch.h"
#include "MainPage.h"
#include "DataSource.h"
using namespace winrt;
using namespace Windows::UI::Xaml;
namespace winrt::TouchExperiment_01::implementation
{
MainPage::MainPage()
{
InitializeComponent();
// load up the source ListView with the name field from out
// in memory database.
auto p = myList().Items();
for (auto a : DataSource::myDataBase) {
p.Append(box_value(a.name));
}
// add a single ListViewItem to the destination ListView so that we
// know where it is.
p = myList2().Items();
p.Append(box_value(L"list"));
}
int32_t MainPage::MyProperty()
{
throw hresult_not_implemented();
}
void MainPage::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
void MainPage::OnSelectionChanged(Windows::Foundation::IInspectable const & target, Windows::UI::Xaml::RoutedEventArgs const & )
{
// the user has selected a different item in the source ListView so we want to display
// the associated description information for the selected ListViewItem.
winrt::Windows::UI::Xaml::Controls::ListView p = target.try_as<winrt::Windows::UI::Xaml::Controls::ListView>();
if (p) {
int iIndex = p.SelectedIndex();
myTextBlock().Text(DataSource::myDataBase[iIndex].description);
}
}
void MainPage::OnListViewDragItemsStarting(Windows::Foundation::IInspectable const & target, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs const & e)
{
// provide the data that we have in the ListView which the user has selected
// to drag to the other ListView. this is the data that will be copied from
// the source ListView to the destination ListView.
auto p = target.try_as<winrt::Windows::UI::Xaml::Controls::ListView>();
if (p) {
int iIndex = p.SelectedIndex();
e.Items().SetAt(0, box_value(iIndex));
}
}
void MainPage::OnListViewDragOver(Windows::Foundation::IInspectable const & target, Windows::UI::Xaml::DragEventArgs const & e)
{
// indicate that we are Copy of data from one ListView to another rather than one of the other
// operations such as Move. This provides the operation type informative user indicator when the
// user is doing the drag operation.
e.AcceptedOperation(Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy);
}
void MainPage::OnListViewDrop(Windows::Foundation::IInspectable const & target, Windows::UI::Xaml::DragEventArgs const & e)
{
// update the destination ListView with the data that was dragged from the
// source ListView.
auto p = target.try_as<winrt::Windows::UI::Xaml::Controls::ListView>();
auto x = e.DataView().GetTextAsync(); // ** this line triggers exception on drop.
}
}
// We need to take a Deferral as we won't be able to confirm the end
// of the operation synchronously
auto def = e->GetDeferral();
create_task(e->DataView->GetTextAsync()).then([def, this, e](String^ s)
{
// Parse the string to add items corresponding to each line
auto wsText = s->Data();
while (wsText) {
auto wsNext = wcschr(wsText, L'\n');
if (wsNext == nullptr)
{
// No more separator
_selection->Append(ref new String(wsText));
wsText = wsNext;
}
else
{
_selection->Append(ref new String(wsText, wsNext - wsText));
wsText = wsNext + 1;
}
}
e->AcceptedOperation = DataPackageOperation::Copy;
def->Complete();
});
#include <experimental\resumable>
#include <pplawait.h>
void MainPage::OnListViewDragItemsStarting(Windows::Foundation::IInspectable const & target, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs const & e)
{
// provide the data that we have in the ListView which the user has selected
// to drag to the other ListView. this is the data that will be copied from
// the source ListView to the destination ListView.
auto p = target.try_as<winrt::Windows::UI::Xaml::Controls::ListView>();
unsigned int n = e.Items().Size();
if (p) {
int iIndex = p.SelectedIndex();
e.Data().Properties().Title(hstring (L"my Title"));
e.Data().SetText(DataSource::myDataBase[iIndex].name.c_str());
e.Data().RequestedOperation(winrt::Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy);
}
}
winrt::Windows::Foundation::IAsyncAction MainPage::OnListViewDrop(Windows::Foundation::IInspectable const & target, Windows::UI::Xaml::DragEventArgs const & e)
{
// update the destination ListView with the data that was dragged from the
// source ListView. the method GetTextAsync() is an asynch method so
// we are using coroutines to get the result of the operation.
// we need to capture the target ListView before doing the co_await
// in a local variable so that we will know which ListView we are to update.
auto p = target.try_as<winrt::Windows::UI::Xaml::Controls::ListView>();
// do the GetTextAsync() and get the result by using coroutines.
auto ss = co_await e.DataView().GetTextAsync();
// update the ListView control that originally triggered this handler.
p.Items().Append(box_value(ss));
}