Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add XamlDragAndDrop sample showing dragging between ListViews #1015

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Add C++ Sample for Moving between ListViews
  • Loading branch information
michael-hawker committed Nov 12, 2018
commit 8218f1eccc7cd842403ea7a936f7930109ad4b62
15 changes: 11 additions & 4 deletions Samples/XamlDragAndDrop/cpp/DragAndDropSampleNative.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<IncludePath>$(VC_IncludePath);$(UniversalCRT_IncludePath);$(WindowsSDK_IncludePath);..\..\..\SharedContent\cpp</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<PropertyGroup>
<IncludePath>$(VC_IncludePath);$(UniversalCRT_IncludePath);$(WindowsSDK_IncludePath);..\..\..\SharedContent\cpp</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
Expand Down Expand Up @@ -158,6 +158,9 @@
<ClInclude Include="Scenario3_StartDragAsync.xaml.h">
<DependentUpon>Scenario3_StartDragAsync.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Scenario4_MoveBetweenListView.xaml.h">
<DependentUpon>Scenario4_MoveBetweenListView.xaml</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="..\..\..\SharedContent\xaml\App.xaml">
Expand All @@ -172,6 +175,7 @@
<Page Include="..\..\..\SharedContent\xaml\Styles.xaml">
<Link>Styles\Styles.xaml</Link>
</Page>
<Page Include="Scenario4_MoveBetweenListView.xaml" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
Expand Down Expand Up @@ -203,6 +207,9 @@
<ClCompile Include="Scenario3_StartDragAsync.xaml.cpp">
<DependentUpon>Scenario3_StartDragAsync.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="Scenario4_MoveBetweenListView.xaml.cpp">
<DependentUpon>Scenario4_MoveBetweenListView.xaml</DependentUpon>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Image Include="Assets\dropcursor.png" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<Page Include="Scenario3_StartDragAsync.xaml" />
<Page Include="..\..\..\SharedContent\cpp\MainPage.xaml" />
<Page Include="..\..\..\SharedContent\xaml\Styles.xaml" />
<Page Include="Scenario4_MoveBetweenListView.xaml" />
</ItemGroup>
<ItemGroup>
<Image Include="Assets\dropcursor.png">
Expand Down
3 changes: 2 additions & 1 deletion Samples/XamlDragAndDrop/cpp/SampleConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ Platform::Array<Scenario>^ MainPage::scenariosInner = ref new Platform::Array<Sc
{
{ "ListView Drag and Drop and Reorder", "SDKTemplate.Scenario1_ListView" },
{ "Drag UI Customization", "SDKTemplate.Scenario2_DragUICustomization" },
{ "StartDragAsync", "SDKTemplate.Scenario3_StartDragAsync" }
{ "StartDragAsync", "SDKTemplate.Scenario3_StartDragAsync" },
{ "Move Between ListViews", "SDKTemplate.Scenario4_MoveBetweenListView" }
};
57 changes: 57 additions & 0 deletions Samples/XamlDragAndDrop/cpp/Scenario4_MoveBetweenListView.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
-->
<Page
x:Class="SDKTemplate.Scenario4_MoveBetweenListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DragAndDropSampleNative"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Margin="0,0,0,10" Grid.ColumnSpan="2">
<TextBlock Text="Description:" Style="{StaticResource SampleHeaderTextStyle}"/>
<TextBlock Style="{StaticResource ScenarioDescriptionTextStyle}" TextWrapping="Wrap" Text="This scenario illustrates how to use ListView's Drag and Drop to reorder single items while maintaining the requested position."/>
</StackPanel>

<TextBlock Grid.Row="1" Margin="8,4"
VerticalAlignment="Bottom"
Text="All Items"/>
<ListView x:Name="SourceListView"
Grid.Row="2" Margin="8,4"
AllowDrop="True" CanReorderItems="True" CanDragItems="True"
DragOver="ListView_DragOver"
Drop="ListView_Drop"
DragItemsStarting="ListView_DragItemsStarting"/>
<TextBlock Grid.Row="1" Grid.Column="1" Margin="8,4"
VerticalAlignment="Bottom"
Text="Selection"/>
<ListView x:Name="TargetListView"
Grid.Row="2" Grid.Column="1" Margin="8,4"
AllowDrop="True" CanReorderItems="True" CanDragItems="True"
DragOver="ListView_DragOver"
Drop="ListView_Drop"
DragItemsStarting="ListView_DragItemsStarting"/>
</Grid>
</Page>
148 changes: 148 additions & 0 deletions Samples/XamlDragAndDrop/cpp/Scenario4_MoveBetweenListView.xaml.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#include "pch.h"
#include "Scenario4_MoveBetweenListView.xaml.h"

using namespace concurrency;
using namespace SDKTemplate;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::ApplicationModel::DataTransfer;

Scenario4_MoveBetweenListView::Scenario4_MoveBetweenListView() : rootPage(MainPage::Current)
{
InitializeComponent();

_source = GetSampleData();
_target = ref new Vector<String^>();
SourceListView->ItemsSource = _source;
TargetListView->ItemsSource = _target;
}

Vector<String^>^ Scenario4_MoveBetweenListView::GetSampleData()
{
return ref new Vector<String^>(
{
ref new String(L"My Research Paper"),
ref new String(L"Electricity Bill"),
ref new String(L"My To-do list"),
ref new String(L"TV sales receipt"),
ref new String(L"Water Bill"),
ref new String(L"Grocery List"),
ref new String(L"Superbowl schedule"),
ref new String(L"World Cup E-ticket")
});
}

/// <summary>
/// DragItemsStarting is called when the Drag and Drop operation starts
/// We take advantage of it to set the content of the DataPackage
/// as well as indicate which operations are supported
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Scenario4_MoveBetweenListView::ListView_DragItemsStarting(Platform::Object^ sender, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs^ e)
{
// Prepare a string with one dragged item per line
// Set the content of the DataPackage
if (e->Items->Size > 0)
{
e->Data->SetText(dynamic_cast<String^>(e->Items->GetAt(0)));
// As we want our Reference list to say intact, we only allow Move
e->Data->RequestedOperation = DataPackageOperation::Move;
}
}

/// <summary>
/// DragOver is called when the dragged pointer moves over a UIElement with AllowDrop=True
/// We need to return an AcceptedOperation != None in either DragOver or DragEnter
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Scenario4_MoveBetweenListView::ListView_DragOver(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{
// Our list only accepts text
e->AcceptedOperation = (e->DataView->Contains(StandardDataFormats::Text)) ? DataPackageOperation::Move : DataPackageOperation::None;
}

/// <summary>
/// We need to return the effective operation from Drop
/// This is not important for our source ListView, but it might be if the user
/// drags text from another source
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Scenario4_MoveBetweenListView::ListView_Drop(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{
// This test is in theory not needed as we returned DataPackageOperation.None if
// the DataPackage did not contained text. However, it is always better if each
// method is robust by itself
if (e->DataView->Contains(StandardDataFormats::Text))
{
// 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, sender, e](String^ s)
{
// Get the lists we need to work with.
auto sourceList = (sender->Equals(TargetListView) ? _source : _target);
auto targetList = (sender->Equals(TargetListView) ? _target : _source);

// Remove item from other list
unsigned j;
if (sourceList->IndexOf(s, &j))
{
sourceList->RemoveAt(j);
}

// First we need to get the position in the List to drop to
auto listview = dynamic_cast<ListView^>(sender);
int index = -1;

// Determine which items in the list our pointer is inbetween.
for (int i = 0; i < listview->Items->Size; i++)
{
auto item = dynamic_cast<ListViewItem^>(listview->ContainerFromIndex(i));

auto p = e->GetPosition(item);

if (p.Y - item->ActualHeight < 0)
{
index = i;
break;
}
}

if (index < 0)
{
// We didn't find a transition point, so we're at the end of the list
targetList->Append(s);
}
else if (index < listview->Items->Size)
{
// Otherwise, insert at the provided index.
targetList->InsertAt(index, s);
}

e->AcceptedOperation = DataPackageOperation::Copy;
def->Complete();
});
}
}
38 changes: 38 additions & 0 deletions Samples/XamlDragAndDrop/cpp/Scenario4_MoveBetweenListView.xaml.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

#pragma once

#include "Scenario4_MoveBetweenListView.g.h"
#include "MainPage.xaml.h"

namespace SDKTemplate
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
[Windows::Foundation::Metadata::WebHostHidden]
public ref class Scenario4_MoveBetweenListView sealed
{
public:
Scenario4_MoveBetweenListView();
private:
MainPage^ rootPage;

Platform::Collections::Vector<Platform::String^>^ GetSampleData();
Platform::Collections::Vector<Platform::String^>^ _source;
Platform::Collections::Vector<Platform::String^>^ _target;

void ListView_DragItemsStarting(Platform::Object^ sender, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs^ e);
void ListView_DragOver(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e);
void ListView_Drop(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e);
};
}