Přetáhnout a pustit

Přetáhnout a pustit je intuitivní způsob, jak přenášet soubory a informace v rámci aplikace nebo mezi aplikacemi na ploše Windows. Přetažení umožňuje uživateli přenášet data mezi aplikacemi nebo v rámci jedné aplikace pomocí standardního gesta (stisknutím a pohnutím prstem, myší nebo perem).

Důležitá rozhraní API: Vlastnost CanDrag, Vlastnost AllowDrop

Zdroj přetažení, což je aplikace nebo oblast, kde se aktivuje gesto přetažení, poskytuje data, která se mají přenést vyplněním objektu datového balíčku, který může obsahovat standardní formáty dat, včetně textu, RTF, HTML, rastrových obrázků, položek úložiště nebo vlastních datových formátů. Zdroj také označuje typ operací, které podporuje: kopírování, přesunutí nebo propojení. Po uvolnění ukazatele dojde k odložení. Cíl vyřazení, což je aplikace nebo oblast pod ukazatelem, zpracuje datový balíček a vrátí typ operace, kterou provedl.

Během přetahování poskytuje uživatelské rozhraní pro přetahování vizuální označení typu operace přetažení. Tuto vizuální zpětnou vazbu původně poskytuje zdroj, ale cíle ji mohou změnit, když nad nimi přejede ukazatel.

Přetahování umožňuje přenos dat mezi aplikacemi nebo v rámci jakéhokoli typu aplikace, včetně desktopových aplikací Win32, ačkoli se tento článek zaměřuje na rozhraní API XAML pro moderní přetahování. Po implementaci funguje přetahování ve všech směrech, včetně z aplikace do aplikace, z aplikace na plochu a z plochy do aplikace.

Tady je přehled toho, co je potřeba udělat, abyste v aplikaci povolili přetažení:

  1. Povolit přetažení prvku tím, že nastavíte jeho vlastnost CanDrag na hodnotu true.
  2. Sestavte datový balíček. Systém zpracovává obrázky a text automaticky, ale pro jiný obsah budete muset zpracovat události DragStarting a DropCompleted a využít je k vytvoření vlastního datového balíčku.
  3. Povolte přetahování nastavením vlastnosti AllowDrop na true u všech prvků, které mohou přijímat přetažený obsah.
  4. Zpracujte událost DragOver a dejte systému vědět, jaký typ operací přetažení může prvek přijímat.
  5. Zpracujte událost Drop a získejte vynechaný obsah.

Povolit přetahování

Chcete-li povolit přetažení prvku, nastavte jeho vlastnost CanDrag na true. Díky tomu lze element (a prvky, které obsahuje, v případě kolekcí, jako je ListView), přetáhnout.

Buďte konkrétní o tom, co je možné přetáhnout. Uživatelé nebudou chtít přetahovat všechno v aplikaci, jenom určité položky, jako jsou obrázky nebo text.

Tady je postup, jak nastavit CanDrag.

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

Pokud nechcete uživatelské rozhraní přizpůsobit (které je popsáno dále v tomto článku), nemusíte provádět žádnou jinou práci, abyste povolili přetahování. Odebrání vyžaduje několik dalších kroků.

Vytvoření datového balíčku

Ve většině případů systém vytvoří datový balíček za vás. Systém automaticky zpracovává:

  • Obrázky
  • Text

V případě jiného obsahu budete muset zpracovat události DragStarting a DropCompleted a použít je k vytvoření vlastní DataPackage.

Poznámka:

Událost DragStarting popsaná zde je součástí UIElement a je správnou událostí pro vytvoření vlastní DataPackage. Toto se liší od události DragStarted u ovládacích prvků Thumb , které se používají pro přetahování posuvníku místo přenosu dat.

Zpracování události DragStarting

Událost DragStarting se aktivuje, když systém zahájí operaci přetažení u elementu, který má CanDrag="True". V obslužné rutině události použijete DragStartingEventArgs k naplnění jeho Vlastnosti Data ( DataPackage) obsahem, který chcete přenést, a nastavíte RequestedOperation tak, aby indikoval, zda je operace kopírování, přesunutí nebo propojení.

Nejprve nastavte element XAML s obslužnou rutinou události jak DragStarting, tak DropCompleted:

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

Potom v kódu zpracujte událost DragStarting , která naplní datový balíček:

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;
}

Pokud při vytváření datového balíčku potřebujete provést asynchronní práci (například čtení souboru), pomocí metody GetDeferral ponechte událost aktivní, dokud nebude dokončena práce:

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();
    }
}

Zpracování události DropCompleted

Událost DropCompleted se vyvolá u zdroje přetažení po dokončení operace přetažení – bez ohledu na to, zda byla položka úspěšně upuštěna nebo zda byla operace přetažení zrušena. Pomocí vlastnosti DropCompletedEventArgs.DropResult určete výsledek a proveďte akci, například odeberte zdrojovou položku, pokud bylo provedeno přesunutí:

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;
    }
}

Úplnou funkční ukázku vlastního přetahování s datovým balíčkem najdete v ukázce přetahování v XAML na GitHubu.

Povolit vyřazení

Následující kód ukazuje, jak lze vlastnost AllowDrop použít k určení, že oblast aplikace je platný cíl přetažení pro přetaženou položku (zadaná oblast nesmí mít null pozadí, musí být schopen přijmout vstup ukazatele a položka nemůže být vyřazena jinam než zadaná oblast).

Poznámka:

Element uživatelského rozhraní má obvykle ve výchozím nastavení null pozadí. Pokud chcete, aby uživatelé mohli umístit položku kamkoli ve vaší aplikaci, pozadí aplikace nemůže mít hodnotu null (nastavte Background="Transparent", pokud pozadí nemá být viditelné).

<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>

Zpracování události DragOver

Událost DragOver se aktivuje, když uživatel přetáhl položku přes aplikaci, ale ještě ji nezahodil. V této obslužné rutině je třeba určit, jaký druh operací vaše aplikace podporuje, pomocí vlastnosti AkceptovanéOperace. Kopírování je nejběžnější.

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

Zpracovat událost Drop

Událost Drop nastane, když uživatel uvolní položky v platné oblasti upuštění. Zpracujte je pomocí vlastnosti DataView .

Pro zjednodušení v následujícím příkladu předpokládáme, že uživatel vynechal jednu fotku a přistupoval k ní přímo. Ve skutečnosti můžou uživatelé současně vyhodit více položek různých formátů. Vaše aplikace by měla tuto možnost zvládnout kontrolou toho, jaké typy souborů byly vyřazeny a kolik jich je, a zpracovat je odpovídajícím způsobem. Měli byste také zvážit upozornění uživatele, pokud se pokouší udělat něco, co vaše aplikace nepodporuje.

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;
        }
    }
}

Přizpůsobení uživatelského rozhraní

Systém poskytuje výchozí uživatelské rozhraní pro přetahování a upouštění. Můžete se ale také rozhodnout přizpůsobit různé části uživatelského rozhraní nastavením vlastních titulků a glyfů nebo tím, že se rozhodnete uživatelské rozhraní vůbec nezobrazovat. Chcete-li přizpůsobit uživatelské rozhraní, použijte DragEventArgs.DragUIOverride vlastnost.

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
}

Otevřete místní nabídku u položky, kterou lze přetáhnout dotykem

Při použití dotykového ovládání přetažení UIElement a otevření místní nabídky sdílejí podobná dotyková gesta; každé začíná stisknutím a podržením. Tady je postup, jak systém nejednoznačně rozlišuje mezi těmito dvěma akcemi prvků v aplikaci, které podporují obojí:

  • Pokud uživatel stiskne a uloží položku a začne ji přetahovat do 500 milisekund, položka se přetáhne a místní nabídka se nezobrazí.
  • Pokud uživatel stiskne a podrží, ale po dobu 500 milisekund nepřetáhne, otevře se místní nabídka.
  • Po otevření místní nabídky se uživatel pokusí položku přetáhnout (bez zvedání prstu), místní nabídka se zavře a přetažení se spustí.

Určení položky v objektu ListView nebo GridView jako složky

Jako složku můžete zadat ListViewItem nebo GridViewItem. To je užitečné zejména pro scénáře TreeView a Průzkumníka souborů. Chcete-li to provést, explicitně nastavte AllowDrop vlastnost True u této položky.

Systém automaticky zobrazí příslušné animace pro přetažení do složky a pro přetažení na položku, která není složkou. Kód aplikace musí i nadále zpracovávat událost Drop u položky složky (stejně jako u položky mimo složku), aby se aktualizoval zdroj dat a přidala odstraněnou položku do cílové složky.

Povolit změnu pořadí pomocí funkce přetáhnutí v ListViews

ListView podporuje změnu pořadí pomocí přetahování, s použitím rozhraní API velmi podobného CanDrop popsaného v tomto článku. Minimálně přidáte vlastnosti AllowDrop a CanReorderItems.

Další informace najdete v tématu ListViewBase.CanReorderItems .

Implementace vlastního přetažení

Třída UIElement provádí většinu práce při implementaci táhni a pusť. Pokud ale chcete, můžete implementovat vlastní verzi pomocí následujících rozhraní API.

Funkčnost Windows App SDK
Microsoft.UI.Input.DragDrop – obor názvů
DragPrimitive DragOperation
Vytvoření datového balíčku DataPackage
Předání přetažení do prostředí DragOperation.StartAsync
Přijmout položku z příkazového prostředí DragDropManager.TargetRequested
IDropOperationTarget

Viz také