Fogd és vidd

Az húzással intuitív módon továbbíthat adatokat egy alkalmazáson belül vagy az asztali Windows alkalmazások között. A húzás és ejtés lehetővé teszi a felhasználó számára, hogy egy szabványos gesztussal (ujjal lenyomva tartva és elhúzva, vagy egérrel, esetleg tollal húzva) adatokat továbbítson az alkalmazások között vagy egy alkalmazáson belül is.

Fontos API-k: CanDrag tulajdonság, AllowDrop tulajdonság

A húzási forrás, amely az az alkalmazás vagy terület, ahol a húzási kézmozdulat aktiválódik, egy olyan adatcsomag-objektum kitöltésével biztosítja az átvitt adatokat, amely szabványos adatformátumokat tartalmazhat, beleértve a szöveget, az RTF-et, a HTML-t, a bitképeket, a tárelemeket vagy az egyéni adatformátumokat. A forrás azt is jelzi, hogy milyen műveleteket támogat: másolás, áthelyezés vagy csatolás. Amikor elengedik a mutatót, leejtés történik. Az egérmutató alatti alkalmazás vagy terület alá tartozó drop target feldolgozza az adatcsomagot, és visszaadja az elvégzett művelet típusát.

Az húzás során a húzási felhasználói felület vizuálisan jelzi az éppen zajló húzási művelet típusát. Ezt a vizuális visszajelzést kezdetben a forrás szolgáltatja, de a célobjektumok módosíthatják, ahogy az egérmutató fölöttük halad át.

A fogd és vidd lehetővé teszi az adatátvitelt bármilyen típusú alkalmazás között vagy egy alkalmazáson belül, beleértve a Win32 asztali alkalmazásokat is, bár ez a cikk a modern fogd és vidd műveletekhez tartozó XAML API-ra összpontosít. A bevezetés után a fogd és vidd minden irányban működik, beleértve az alkalmazásból alkalmazásba, az alkalmazásból az asztalra és az asztalról alkalmazásba történő áthúzást is.

Az alábbiakban áttekintheti, hogy mit kell tennie a húzás engedélyezéséhez az alkalmazásban:

  1. Az elemek húzásának engedélyezéséhez állítsa a CanDrag tulajdonságát igaz értékre.
  2. Hozza létre az adatcsomagot. A rendszer automatikusan kezeli a képeket és a szöveget, más tartalmak esetében azonban kezelnie kell a DragStarting és DropCompleted eseményeket, és ezeket kell használnia saját adatcsomag létrehozásához.
  3. Az eldobás engedélyezéséhez állítsa az AllowDrop tulajdonságot igaz értékre minden olyan elemen, amely képes fogadni az eldobott tartalmat.
  4. Kezelje a DragOver eseményt, hogy a rendszer tudja, milyen típusú húzási műveleteket kaphat az elem.
  5. Dolgozza fel a Drop eseményt az elvetett tartalom fogadásához.

Húzás lehetővé tétele

Egy elem húzásának engedélyezéséhez állítsa az CanDrag tulajdonságot igazra. Így az elem – és a benne található elemek – a ListView-hoz hasonló gyűjtemények esetében húzhatóvá lesznek.

Legyen konkrét abban, hogy mi húzható. A felhasználók nem szeretnének mindent húzni az alkalmazásban, csak bizonyos elemeket, például képeket vagy szöveget.

Így állíthatja be CanDrag.

<Image x:Name="Image" CanDrag="True" Margin="10,292,10,0" Height="338"/>

A húzás engedélyezéséhez nem kell más munkát végeznie, kivéve, ha testre szeretné szabni a felhasználói felületet (amelyről a cikk későbbi részében is szó lesz). A leejtéshez további lépésekre van szükség.

Adatcsomag létrehozása

A legtöbb esetben a rendszer létrehoz egy adatcsomagot. A rendszer automatikusan kezeli a következőt:

  • Képek
  • Szöveg

Más tartalmak esetében kezelnie kell a DragStarting és a DropCompleted eseményeket, és ezeket használva kell létrehoznia a saját DataPackagecsomagját.

Megjegyzés:

Az itt ismertetett DragStarting esemény a UIElement része, és az egyéni DataPackageelemek létrehozásához megfelelő esemény. Ez eltér a hüvelykujj-vezérlőkDragStarted eseményétől, amelyet az adatátvitel helyett csúszkastílusú húzáshoz használnak.

A DragStarting esemény kezelése

A DragStarting esemény akkor aktiválódik, amikor a rendszer elindít egy húzási műveletet egy olyan elemen, amely rendelkezik CanDrag="True". Az eseménykezelőben a DragStartingEventArgs használatával töltse fel a Data tulajdonságát (egy DataPackage) az átvinni kívánt tartalommal, és állítsa be a RequestedOperation tulajdonságot annak jelzésére, hogy a művelet másolás, áthelyezés vagy hivatkozás legyen.

Először állítsa be az XAML-elemet úgy, hogy DragStarting és DropCompleted eseménykezelővel is rendelkezzen:

<TextBlock x:Name="DraggableText" CanDrag="True"
           DragStarting="DraggableText_DragStarting"
           DropCompleted="DraggableText_DropCompleted"
           Text="Drag this text to another location"/>

Ezután a mögöttes kódban kezelje a DragStarting eseményt az adatcsomag feltöltéséhez:

private void DraggableText_DragStarting(UIElement sender, DragStartingEventArgs args)
{
    // Add the text content to the data package
    args.Data.SetText(((TextBlock)sender).Text);

    // Indicate that both Copy and Move are acceptable
    args.Data.RequestedOperation = DataPackageOperation.Copy | DataPackageOperation.Move;
}

Ha aszinkron munkát kell végeznie az adatcsomag létrehozása során (például egy fájl olvasása), a GetDeferral metódussal aktív állapotban tarthatja az eseményt a munka befejezéséig:

private async void DraggableText_DragStarting(UIElement sender, DragStartingEventArgs args)
{
    var deferral = args.GetDeferral();
    try
    {
        // Perform async work here, for example loading file content
        string content = await LoadCustomTextAsync();
        args.Data.SetText(content);
        args.Data.RequestedOperation = DataPackageOperation.Copy;
    }
    finally
    {
        deferral.Complete();
    }
}

A DropCompleted esemény kezelése

A DropCompleted esemény a húzási művelet befejeződése után aktiválódik a húzási forráson – függetlenül attól, hogy az elem sikeresen el lett-e vetve, vagy a húzást megszakították. A DropCompletedEventArgs.DropResult tulajdonság használatával határozza meg az eredményt, és hajtsa végre a műveletet, például távolítsa el a forráselemet, ha áthelyezés történt:

private void DraggableText_DropCompleted(UIElement sender, DropCompletedEventArgs args)
{
    if (args.DropResult == DataPackageOperation.Move)
    {
        // The target accepted the data as a Move, so clear the source
        ((TextBlock)sender).Text = string.Empty;
    }
}

Egy adatcsomagot használó egyéni fogd és vidd teljes, működő példájáért lásd a GitHubon található XAML-es fogd és vidd mintát.

Az elvetés engedélyezése

Az alábbi korrektúra bemutatja, hogyan lehet az AllowDrop tulajdonságot használni annak meghatározására, hogy az alkalmazás egy területe érvényes célhely-e egy húzott elemhez (a megadott terület nem rendelkezhet null háttérrel, képesnek kell lennie a mutató bemenetének fogadására, és az elemet nem lehet a megadott területtől eltérő helyre elvetni).

Megjegyzés:

A felhasználói felületi elemek általában alapértelmezés szerint null háttérrel rendelkeznek. Ha azt szeretné, hogy a felhasználók bármelyik helyen el tudjanak helyezni egy elemet az alkalmazáson belül, az alkalmazás háttere nem lehet üres (állítsa be Background="Transparent", ha a háttér nem látható).

<Grid AllowDrop="True" DragOver="Grid_DragOver" Drop="Grid_Drop"
      Background="LightBlue" Margin="10,10,10,353">
    <TextBlock>Drop anywhere in the blue area</TextBlock>
</Grid>

A DragOver esemény kezelése

A DragOver esemény akkor aktiválódik, ha egy felhasználó áthúzott egy elemet az alkalmazáson, de még nem dobta el. Ebben a kezelőben meg kell adnia, hogy az alkalmazás milyen műveleteket támogat az AcceptedOperation tulajdonság használatával. A másolás a leggyakoribb.

private void Grid_DragOver(object sender, DragEventArgs e)
{
    e.AcceptedOperation = DataPackageOperation.Copy;
}

A Drop esemény feldolgozása

A Drop esemény akkor következik be, ha a felhasználó egy érvényes legördülő területen ad ki elemeket. Feldolgozhatja őket a DataView tulajdonság használatával.

Az alábbi példában az egyszerűség kedvéért feltételezzük, hogy a felhasználó ledobott egy fényképet, és közvetlenül hozzáférünk. A valóságban a felhasználók egyszerre több különböző formátumú elemet is elvethetnek. Az alkalmazásnak ezt a lehetőséget úgy kell kezelnie, hogy ellenőrzi, hogy milyen típusú fájlokat dobtak el, és hány fájl van, és ennek megfelelően dolgozza fel őket. Érdemes lehet értesíteni a felhasználót, ha olyasmit próbálnak végrehajtani, amit az alkalmazás nem támogat.

private async void Grid_Drop(object sender, DragEventArgs e)
{
    if (e.DataView.Contains(StandardDataFormats.StorageItems))
    {
        var items = await e.DataView.GetStorageItemsAsync();
        if (items.Count > 0)
        {
            var storageFile = items[0] as StorageFile;
            var bitmapImage = new BitmapImage();
            bitmapImage.SetSource(await storageFile.OpenAsync(FileAccessMode.Read));
            // Set the image on the main page to the dropped image
            Image.Source = bitmapImage;
        }
    }
}

A felhasználói felület testreszabása

A rendszer alapértelmezett felhasználói felületet biztosít a húzáshoz és az ejtéshez. A felhasználói felület különböző részeit azonban egyéni feliratok és karakterjelek beállításával is testre szabhatja, vagy úgy is dönthet, hogy egyáltalán nem jelenít meg felhasználói felületet. A felhasználói felület testreszabásához használja a DragEventArgs.DragUIOverride tulajdonságot.

private void Grid_DragOverCustomized(object sender, DragEventArgs e)
{
    e.AcceptedOperation = DataPackageOperation.Copy;
    e.DragUIOverride.Caption = "Custom text here"; // Sets custom UI text
    // Sets a custom glyph
    e.DragUIOverride.SetContentFromBitmapImage(
        new BitmapImage(
            new Uri("ms-appx:///Assets/CustomImage.png", UriKind.RelativeOrAbsolute)));
    e.DragUIOverride.IsCaptionVisible = true; // Sets if the caption is visible
    e.DragUIOverride.IsContentVisible = true; // Sets if the dragged content is visible
    e.DragUIOverride.IsGlyphVisible = true; // Sets if the glyph is visibile
}

Nyisson meg egy helyi menüt egy érintéssel húzható elemen

Amikor érintést használ, a UIElement húzása és a helyi menü megnyitása hasonló érintéses kézmozdulatokat használ; mindegyik megnyomással és lenyomva tartással kezdődik. A rendszer így egyértelműsíti az alkalmazás két olyan elemét, amelyek támogatják a két műveletet:

  • Ha egy felhasználó lenyom és tart egy elemet, és 500 ezredmásodpercen belül elkezdi húzni, a rendszer húzza az elemet, és a helyi menü nem jelenik meg.
  • Ha a felhasználó lenyomja és tartja, de nem húzza 500 milliszekundumon belül, megnyílik a helyi menü.
  • A helyi menü megnyitása után, ha a felhasználó megpróbálja húzni az elemet (az ujjának felemelése nélkül), a helyi menü el lesz utasítva, és a húzás elindul.

Elem kijelölése a ListView-ban vagy a GridView-ban mappaként

Mappaként megadhat egy ListViewItem vagy GridViewItem mappát. Ez különösen hasznos a TreeView és a Fájlkezelő esetében. Ehhez állítsa az AllowDrop tulajdonságot úgy, hogy Igaz az adott elemen.

A rendszer automatikusan megjeleníti a megfelelő animációkat a mappába való bedobáshoz egy nem mappaelem helyett. Az alkalmazás kódjának továbbra is kezelnie kell az Drop eseményt a mappaelemen (valamint a nem mappaelemen), hogy frissítse az adatforrást, és hozzáadhassa az elvetett elemet a célmappához.

Az elemek áthúzással történő átrendezésének engedélyezése a listanézetekben

ListView támogatja a dobozból való áthúzásalapú átrendezést a jelen cikkben ismertetett CanDrop API-hoz nagyon hasonló API használatával. Legalább adja hozzá az AllowDrop és CanReorderItems tulajdonságokat.

További információért lásd ListViewBase.CanReorderItems.

Egyéni húzás és ejtés implementálása

A UIElement osztály végzi el a húzás és ejtés végrehajtásának munkájának nagy részét az Ön számára. Ha azonban szeretné, az alábbi API-k használatával implementálhatja a saját verzióját.

Funkcionalitás Windows App SDK
Microsoft.UI.Input.DragDrop névtér
DragPrimitive DragOperation
Adatcsomag létrehozása DataPackage
Add át a húzást a shellnek DragOperation.StartAsync
Parancshéjból érkező csepp fogadása DragDropManager.TargetRequested
IDropOperationTarget

Lásd még