Démarrage rapide : glissement de contenu

Applies to Windows only

Vous pouvez faire glisser du texte, des images ou d’autres données dans un GridView ou un ListView dans le but de les réorganiser, comme vous pouvez faire glisser des éléments vers d’autres types de contrôles.

Dans une application du Windows Store, vous pouvez réorganiser les éléments d’un GridView ou d’un ListView en les faisant glisser au moyen d’une souris, d’un mouvement tactile ou de la voix. Vous pouvez également faire glisser un élément d’un GridView ou d’un ListView unique vers un autre contrôle XAML. Pour faire glisser des éléments à partir d’un GridView ou d’un ListView, affectez la valeur True à l’attribut CanDragItems. Pour permettre à un contrôle d’accepter les éléments glissés, affectez la valeur True à l’attribut AllowDrop.

Vous pouvez appliquer des animations aux opérations de glissement. Suivez les instructions générales fournies dans Recommandations sur les animations de glissement, même si cette rubrique concerne JavaScript. L’article Animation de votre interface utilisateur indique comment appliquer des animations de glissement en XAML.

Le glissement entre différentes applications n’est pas prise en charge, mais vous pouvez utiliser les API de partage ou le Presse-papiers pour transférer des données dans ces cas de figure. Toutes les API de transfert de données ont certains types en commun. Tel est le cas de la classe Windows::ApplicationModel::DataTransfer ::DataPackage et de l’énumération Windows::ApplicationModel::DataTransfer ::StandardDataFormats. Dans une opération de glissement, la classe DataPackage est utilisée pour inclure les données transférées dans un wrapper, tandis que l’énumération StandardDataFormats définit les formats pour lesquels DataPackage fournit des méthodes Set* spéciales. Parmi elles figurent Text, Bitmap, Html, Rtf, Uri et des collections d’objet StorageItem. La classe DataPackageView fournit les méthodes Get* asynchrones que vous utilisez dans le gestionnaire d’événements Drop pour récupérer les données. Vous pouvez également faire glisser des objets définis par l’utilisateur à l’aide de la méthode DataPackage::SetData et des méthodes DataPackageView::GetDataAsync.

Pour permettre le glissement d’éléments dans un GridView ou un ListView

Il n’est pas difficile d’autoriser le glissement d’éléments dans un GridView ou un ListView. Il suffit de définir dans le code XAML les attributs du contrôle suivants : AllowDrop="True" CanDragItems="True" CanReorderItems="True"

Étapes de base du glissement

Quel que soit le type de données que vous transférez, une opération de glissement entre différents contrôles comporte deux étapes de base :

  1. Traitez l’événement Windows::UI::Xaml::Controls::DragItemsStarting dans la source où débute l’action de glissement, qui peut être un Windows::UI::Xaml::Controls::GridView ou un Windows::UI::Xaml::Controls::ListView. Le paramètre DragItemsStartingEventArgs contient une référence à l’élément ou aux éléments glissés. Le paramètre contient également une propriété Data qui correspond au DataPackage qui sera transmis à la cible de dépôt. Dans le gestionnaire d’événements, obtenez les données que vous voulez transmettre à partir de la collection DragItemsStartingEventArgs::Items, puis servez-vous de ces données pour remplir la propriété Data selon les nécessités de votre scénario.

  2. Traitez l’événement Windows::UI::Xaml::Controls::Drop dans la cible de dépôt. Récupérez l’objet DataPackage qui est transmis, appelez GetView pour obtenir sa propriété DataPackageView, puis utilisez sa méthode Get* pour accéder aux données que vous avez stockées précédemment dans l’événement DragItemsStarting. Une cible de dépôt peut être un contrôle XAML qui prend en charge l’événement de dépôt (« Drop »).

D’autres événements (DragEnter, DragLeave et DragOver) servent essentiellement à créer des animations ou d’autres effets visuels, mais ils ne sont pas essentiels à l’opération de transfert de données de base proprement dite.

Pour faire glisser du texte

Dans l’exemple suivant, supposons que la source de dépôt est un GridView qui contient des éléments String, et que DragItemsStarting_1 est le gestionnaire d’événements pour l’événement DragItemsStarting qui est déclenché par le GridView. Si la propriété GridView:: SelectionMode a la valeur Multiple, la collection Items peut contenir plusieurs éléments. Dans cet exemple, en supposant que la propriété SelectionMode a la valeur Single, nous pouvons considérer que l’élément déplacé se trouve à la position 0.

Déplacement (glisser) :

void DragDrop::DragText::DragTextGridView_DragItemsStarting_1(Platform::Object^ sender, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs^ e)
{    
    auto mytxt = safe_cast<String^>(e->Items->GetAt(0));
    e->Data->SetText(mytxt);
}
private void DragTextGridView_DragItemsStarting_1(object sender, DragItemsStartingEventArgs e)
{
    var mytxt = e.Items[0] as String;
    if (mytxt != null)
    {
        e.Data.SetText(mytxt);
    }
}

Dépôt :

L’exemple suivant montre comment traiter l’événement Drop. Supposons en l’espèce que la cible de dépôt est un élément XAMLTextBlock.

void DragDrop::DragText::DropTextHere_Drop_1(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{
    using namespace concurrency;
    using namespace Windows::ApplicationModel::DataTransfer;

    DataPackageView^ dataView = e->Data->GetView();
    create_task(dataView->GetTextAsync())
    .then([this, sender](String^ txt)
    {
        TextBlock^ tb = safe_cast<TextBlock^>(sender);
        tb->Text = txt;
    });
}
private async void DropTextHere_Drop_1(object sender, DragEventArgs e)
{
    var dataView = e.Data.GetView();
    var tb = sender as TextBlock;
    if (sender != null)
    {
        tb.Text = await dataView.GetTextAsync();
    }
}

Pour faire glisser des images bitmap

Si un objet BitmapImage est obtenu à partir d’un fichier, utilisez les méthodes DataPackage::SetStorageItems et DataPackageView::GetStorageItemsAsync pour le faire glisser en tant que IStorageItem. Par ailleurs, si vous devez créer un GridView ou un ListView d’objets BitmapImage basés sur des fichiers pouvant être glissés, la meilleure approche consiste à créer un objet de wrapper pouvant être lié qui contient en tant que propriétés publiques le BitmapImage et le StorageFile d’origine, et peut-être d’autres informations telles que le nom de fichier ou des attributs. Comme un objet IStorageItem en tant que tel ne peut pas être lié, il n’est pas facile de l’afficher dans un GridView.

Important  Bien qu’il soit possible d’utiliser la classe FileInformation pour lier des objets de fichier virtualisés à un contrôle XAML, les objets virtualisés ne peuvent pas être glissés facilement.

Dans l’exemple suivant, supposons que la source du déplacement est un ListView qui est lié aux données d’une liste d’objets PhotoWrapper définis par l’utilisateur. Chaque PhotoWrapper contient un BitmapImage et l’objet StorageFile qui a été obtenu à l’ouverture initiale du fichier. Le DataTemplate au niveau du ListView se lie à la propriété ImageFile.

    [Windows::UI::Xaml::Data::Bindable]
    public ref class PhotoWrapper sealed
    {
    public:
        property Windows::UI::Xaml::Media::Imaging::BitmapImage^ Thumbnail;
        property Windows::Storage::StorageFile^ ImageFile;
    };
    public sealed class PhotoWrapper
    {
        public BitmapImage Thumbnail { get; set; }
        public StorageFile ImageFile { get; set; }
    }

Déplacement (glisser) :

Le gestionnaire d’événements DragItemsStarting ci-dessous montre comment créer une liste d’un ou plusieurs objets IStorageItem dans l’opération de déplacement (glisser) et comment les insérer dans le DataPackage.

void DragDrop::DragImage::ListView_DragItemsStarting_1(Platform::Object^ sender, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs^ e)
{
    IVector<IStorageItem^>^ selectedFiles = ref new Vector<IStorageItem^>();
    for (unsigned int i = 0; i < e->Items->Size; i++)
    {
        PhotoWrapper^ wrapper = safe_cast<PhotoWrapper^>(e->Items->GetAt(i));
        selectedFiles->Append(wrapper->ImageFile);
    }

    e->Data->SetStorageItems(selectedFiles);
}
        void ListView_DragItemsStarting_1(object sender, DragItemsStartingEventArgs e)
        {
            IList<IStorageItem> selectedFiles = new List<IStorageItem>();
            foreach (var item in e.Items)
            {
                var wrapper = item as PhotoWrapper;
                selectedFiles.Add(wrapper.ImageFile);
            }

            e.Data.SetStorageItems(selectedFiles);
        }

Dépôt :

Dans l’événement de dépôt, obtenez la propriété en lecture seule DataPackageView et appelez la méthode OpenReadAsync pour récupérer le flux, puis créez un BitmapImage à partir de celui-ci. À l’issue de l’opération, définissez la propriété Source sur le contrôle Image, puis supprimez l’objet PhotoWrapper correspondant de la liste source.

void DragDrop::DragImage::ListView_Drop_1(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{
    DataPackageView^ dpView = e->Data->GetView();

    create_task(dpView->GetStorageItemsAsync())
    .then([this](IVectorView<IStorageItem^>^ images)
    {
        for (unsigned int i = 0; i < images->Size; i++)
        {
            create_task([images, i, this]()
            {
                // Get a stream from the file object.
                IStorageFile^ file = safe_cast<IStorageFile^>(images->GetAt(i));
                return file->OpenReadAsync();
            }).then([this](IRandomAccessStreamWithContentType^ s)
            {
                // Set the stream as the bitmap source
                BitmapImage^ bi = ref new BitmapImage();
                bi->SetSourceAsync(s);
                return bi;
            }).then([this](BitmapImage^ bi)
            {
                // Add the BitmapImage to the source list.
                // The update will be reflected in the ListView.
                m_targetImages->Append(bi);
            });
        }        
    });
}
        private async void ListView_Drop_1(object sender, DragEventArgs e)
        {
            var dpView = e.Data.GetView();
            var images = await dpView.GetStorageItemsAsync();

            foreach (var image in images)
            {
                // Get a stream from the file object.
                IStorageFile file = image as StorageFile;
                var randomStream = await file.OpenReadAsync();

                // Set the stream as the bitmap source
                BitmapImage bi = new BitmapImage();
                await bi.SetSourceAsync(randomStream);

                // Add the BitmapImage to the source list.
                // The update will be reflected in the ListView.
                m_targetImages.Add(bi);
            }
        }
  

Pour faire glisser des objets définis par l’utilisateur

Vous pouvez faire glisser des objets personnalisés en les insérant dans le conteneur associatif DataPackage::Properties. Dans ce cas, étant donné que le DataPackage n’a pas connaissance des données, vous devez fournir une clé de chaîne décrivant le format de données. Dans une opération de glissement, votre application est la seule à utiliser la chaîne de format. Par conséquent, vous n’avez pas besoin de choisir un nom intelligible. Il vous suffit de fournir la même chaîne lorsque vous récupérez les données. Dans cet exemple, la même clé est fournie pour tous les éléments, mais vous pouvez aussi fournir une clé individuelle pour chaque élément.

Dans l’exemple suivant, supposons que nous avons une classe City qui peut être liée et que nous voulons faire glisser un ou plusieurs objets City de GridView vers ListView.

    [Windows::UI::Xaml::Data::Bindable]
    public ref class City sealed
    {
    public:
        City(Platform::String^ name, int pop)
        {
            this->Name = name;
            this->Population = pop;
        }
        property Platform::String^ Name;
        property int Population;
    };
    public sealed class City
    {
        public City(String name, int pop)
        {
            this.Name = name;
            this.Population = pop;
        }
        public String Name { get; set; }
        public int Population { get; set; }
    }

Déplacement (glisser) :

void DragDrop::MainPage::GridView_DragItemsStarting_1(Platform::Object^ sender, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs^ e)
{
    for (auto item : e->Items)
    {    
        // If you want to drop only a subset of the dragged items,
        // then make each key unique.    
        e->Data->Properties->Insert("MyApp.MyCity", item);
    }
}
void GridView_DragItemsStarting_1(Object sender, DragItemsStartingEventArgs e)
{
    foreach(var item in e.Items)
    {
        // If you want to drop only a subset of the dragged items,
        // then make each key unique. 
        e.Data.Properties.Add("MyApp.MyCity", item);
     }
}

Dépôt :

Dans l’opération de dépôt en C++, les éléments sont extraits de l’objet DataPackage, convertis à nouveau en City (leur type d’origine), puis copiés dans la source de données pour la cible de dépôt.

void DragDrop::MainPage::ListViewDropTarget_Drop_1(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{    
    DataPackageView^ dpView = e->Data->GetView();
    for (auto prop : dpView->Properties)
    {
        auto city = safe_cast<City^>(prop->Value);
        m_dropTargetItems->Append(city);
    }  
}
void ListViewDropTarget_Drop_1(Object sender, DragEventArgs e)
{
    DataPackageView dpView = e.Data.GetView();
    foreach (var prop in dpView.Properties)
    {
        var city = prop.Value as City;
        m_dropTargetItems.Add(city);
    }
}