Delen via


Overzicht: Slepen en neerzetten inschakelen voor een gebruikersbesturingselement

In dit scenario ziet u hoe u een aangepast gebruikersbesturingselement maakt dat kan deelnemen aan gegevensoverdracht met slepen en neerzetten in Windows Presentation Foundation (WPF).

In deze doorloop maakt u een aangepaste WPF UserControl die een cirkelvorm vertegenwoordigt. U implementeert functionaliteit op het besturingselement om gegevensoverdracht via slepen en neerzetten in te schakelen. Als u bijvoorbeeld van het ene besturingselement Cirkel naar het andere sleept, worden de opvulkleurgegevens gekopieerd van de broncirkel naar het doel. Als u van een cirkelcontrole naar een TextBox sleept, wordt de tekenreeksweergave van de opvulkleur gekopieerd naar de TextBox. U maakt ook een kleine toepassing met twee paneelbesturingselementen en een TextBox om de functionaliteit voor slepen en neerzetten te testen. U schrijft code waarmee de deelvensters gevallen cirkelgegevens kunnen verwerken, waardoor u cirkels kunt verplaatsen of kopiëren van de kinderenverzameling van het ene deelvenster naar het andere.

Deze handleiding illustreert de volgende taken:

  • Maak een aangepast gebruikersbeheer.

  • Schakel het gebruikersbeheer in als een sleepbron.

  • Schakel het gebruikersbeheer in als een doel voor neerzetten.

  • Schakel een paneel in om gegevens te ontvangen die vanuit de gebruikersinterface worden neergezet.

Vereiste voorwaarden

U hebt Visual Studio nodig om deze walkthrough te voltooien.

Het toepassingsproject maken

In deze sectie maakt u de toepassingsinfrastructuur aan, dat een hoofdpagina met twee panelen en een TextBox omvat.

  1. Maak een nieuw WPF-toepassingsproject in Visual Basic of Visual C# met de naam DragDropExample. Zie Walkthrough: Mijn eerste WPF-bureaubladtoepassingvoor meer informatie.

  2. Open MainWindow.xaml.

  3. Voeg de volgende markeringen toe tussen de openings- en eindtags Grid .

    Met deze markering wordt de gebruikersinterface voor de testtoepassing gemaakt.

    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <StackPanel Grid.Column="0"
                Background="Beige">
        <TextBox Width="Auto" Margin="2"
                 Text="green"/>
    </StackPanel>
    <StackPanel Grid.Column="1"
                Background="Bisque">
    </StackPanel>
    

Een nieuw gebruikersbeheer toevoegen aan het project

In deze sectie voegt u een nieuw gebruikersbeheer toe aan het project.

  1. Selecteer Gebruikersbeheer toevoegen in het menu Project.

  2. Wijzig in het dialoogvenster Nieuw item toevoegen de naam in Circle.xamlen klik op Toevoegen.

    Circle.xaml en de bijbehorende code-behind worden toegevoegd aan het project.

  3. Open Circle.xaml.

    Dit bestand bevat de gebruikersinterface-elementen van het gebruikersbesturingselement.

  4. Voeg de volgende markeringen toe aan de hoofdmap Grid om een eenvoudig gebruikersbesturingselement te maken met een blauwe cirkel als gebruikersinterface.

    <Ellipse x:Name="circleUI" 
             Height="100" Width="100"
             Fill="Blue" />
    
  5. Open Circle.xaml.cs of Circle.xaml.vb.

  6. Voeg in C# de volgende code toe na de parameterloze constructor om een kopieerconstructor te maken. Voeg in Visual Basic de volgende code toe om zowel een parameterloze constructor als een kopieerconstructor te maken.

    Als u wilt toestaan dat de gebruikerscontrole kan worden gekopieerd, voegt u een copyconstructormethode toe aan het code-behind-bestand. In het vereenvoudigde gebruikersbeheer van Circle kopieert u alleen de opvulling en de grootte van het gebruikersbeheer.

    public Circle(Circle c)
    {
        InitializeComponent();
        this.circleUI.Height = c.circleUI.Height;
        this.circleUI.Width = c.circleUI.Height;
        this.circleUI.Fill = c.circleUI.Fill;
    }
    
    Public Sub New()
        ' This call is required by the designer.
        InitializeComponent()
    End Sub
    
    Public Sub New(ByVal c As Circle)
        InitializeComponent()
        Me.circleUI.Height = c.circleUI.Height
        Me.circleUI.Width = c.circleUI.Height
        Me.circleUI.Fill = c.circleUI.Fill
    End Sub
    

Het gebruikersbeheer toevoegen aan het hoofdvenster

  1. Open MainWindow.xaml.

  2. Voeg de volgende XAML toe aan de openingstag Window om een XML-naamruimtereferentie te maken naar de huidige toepassing.

    xmlns:local="clr-namespace:DragDropExample"
    
  3. Voeg in het eerste StackPaneldeelvenster de volgende XAML toe om twee exemplaren van het besturingselement Circle-gebruiker te maken.

    <local:Circle Margin="2" />
    <local:Circle Margin="2" />
    

    De volledige XAML voor het deelvenster ziet er als volgt uit.

    <StackPanel Grid.Column="0"
                Background="Beige">
        <TextBox Width="Auto" Margin="2"
                 Text="green"/>
        <local:Circle Margin="2" />
        <local:Circle Margin="2" />
    </StackPanel>
    <StackPanel Grid.Column="1"
                Background="Bisque">
    </StackPanel>
    

Draagbronevenementen implementeren in de gebruikerscontrole

In deze sectie overschrijft u de OnMouseMove methode en start u de bewerking slepen en neerzetten.

Als een sleep wordt gestart (een muisknop wordt ingedrukt en de muis wordt verplaatst), verpakt u de over te brengen gegevens in een DataObject. In dit geval worden met het besturingselement Cirkel drie gegevensitems verpakt; een tekenreeksweergave van de opvulkleur, een dubbele weergave van de hoogte en een kopie van zichzelf.

Om een drag-and-drop-bewerking te starten

  1. Open Circle.xaml.cs of Circle.xaml.vb.

  2. Voeg de volgende OnMouseMove overschrijving toe om de afhandeling van de klasse voor de MouseMove gebeurtenis te verzorgen.

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            // Package the data.
            DataObject data = new DataObject();
            data.SetData(DataFormats.StringFormat, circleUI.Fill.ToString());
            data.SetData("Double", circleUI.Height);
            data.SetData("Object", this);
    
            // Initiate the drag-and-drop operation.
            DragDrop.DoDragDrop(this, data, DragDropEffects.Copy | DragDropEffects.Move);
        }
    }
    
    Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Input.MouseEventArgs)
        MyBase.OnMouseMove(e)
        If e.LeftButton = MouseButtonState.Pressed Then
            ' Package the data.
            Dim data As New DataObject
            data.SetData(DataFormats.StringFormat, circleUI.Fill.ToString())
            data.SetData("Double", circleUI.Height)
            data.SetData("Object", Me)
    
            ' Inititate the drag-and-drop operation.
            DragDrop.DoDragDrop(Me, data, DragDropEffects.Copy Or DragDropEffects.Move)
        End If
    End Sub
    

    Met deze OnMouseMove overschrijving worden de volgende taken uitgevoerd:

    • Controleert of de linkermuisknop wordt ingedrukt terwijl de muis beweegt.

    • Verpakt de cirkelgegevens in een DataObject. In dit geval verpakt het besturingselement Circle drie gegevensitems; een tekenreeksweergave van de opvulkleur, een dubbele weergave van de hoogte en een kopie van zichzelf.

    • Roept de statische DragDrop.DoDragDrop methode aan om de bewerking slepen en neerzetten te initiëren. U geeft de volgende drie parameters door aan de DoDragDrop methode:

      • dragSource – Een verwijzing naar dit besturingselement.

      • data – De DataObject gemaakt in de eerdere code.

      • allowedEffects – De toegestane bewerkingen voor slepen en neerzetten zijn Copy of Move.

  3. Druk op F5- om de toepassing te bouwen en uit te voeren.

  4. Klik op een van de cirkelbesturingen en sleep deze over de panelen, de andere cirkel en de TextBox. Wanneer u over de TextBox sleept, verandert de cursor om een verplaatsing aan te geven.

  5. Terwijl u een cirkel over de TextBoxcirkel sleept, drukt u op Ctrl . U ziet hoe de cursor verandert om een kopie aan te geven.

  6. Sleep een cirkel naar de TextBox. De tekenreeksweergave van de opvulkleur van de cirkel wordt toegevoegd aan de TextBox.

    Tekenreeksweergave van de opvulkleur van de cirkel

De cursor wordt standaard gewijzigd tijdens een slepen-en-neerzetten-bewerking om aan te geven welk effect het verwijderen van de gegevens heeft. U kunt de feedback die aan de gebruiker wordt gegeven aanpassen door de GiveFeedback gebeurtenis te verwerken en een andere cursor in te stellen.

Feedback geven aan de gebruiker

  1. Open Circle.xaml.cs of Circle.xaml.vb.

  2. Voeg de volgende OnGiveFeedback overschrijving toe om de afhandeling van de klasse voor de GiveFeedback gebeurtenis te verzorgen.

    protected override void OnGiveFeedback(GiveFeedbackEventArgs e)
    {
        base.OnGiveFeedback(e);
        // These Effects values are set in the drop target's
        // DragOver event handler.
        if (e.Effects.HasFlag(DragDropEffects.Copy))
        {
            Mouse.SetCursor(Cursors.Cross);
        }
        else if (e.Effects.HasFlag(DragDropEffects.Move))
        {
            Mouse.SetCursor(Cursors.Pen);
        }
        else
        {
            Mouse.SetCursor(Cursors.No);
        }
        e.Handled = true;
    }
    
    Protected Overrides Sub OnGiveFeedback(ByVal e As System.Windows.GiveFeedbackEventArgs)
        MyBase.OnGiveFeedback(e)
        ' These Effects values are set in the drop target's
        ' DragOver event handler.
        If e.Effects.HasFlag(DragDropEffects.Copy) Then
            Mouse.SetCursor(Cursors.Cross)
        ElseIf e.Effects.HasFlag(DragDropEffects.Move) Then
            Mouse.SetCursor(Cursors.Pen)
        Else
            Mouse.SetCursor(Cursors.No)
        End If
        e.Handled = True
    End Sub
    

    Met deze OnGiveFeedback overschrijving worden de volgende taken uitgevoerd:

    • Controleert de Effects waarden die zijn ingesteld in de event handler van het neervaldoel DragOver.

    • Hiermee stelt u een aangepaste cursor in op basis van de Effects waarde. De cursor is bedoeld om visuele feedback te geven aan de gebruiker over welk effect het verwijderen van de gegevens zal hebben.

  3. Druk op F5- om de toepassing te bouwen en uit te voeren.

  4. Sleep een van de besturingselementen van de cirkel over de panelen, de andere cirkel en de TextBox. U ziet dat de cursors nu de aangepaste cursors zijn die u hebt opgegeven in de OnGiveFeedback overschrijving.

    Slepen en neerzetten met aangepaste cursors

  5. Selecteer de tekst green uit de TextBox.

  6. Sleep de green tekst naar een cirkel besturingselement. U ziet dat de standaardcursors worden weergegeven om de effecten van de bewerking slepen en neerzetten aan te geven. De feedbackcursor wordt altijd ingesteld door de dragbron.

Doelevenementen voor neerzetten implementeren in het gebruikersbeheer

In deze sectie geeft u op dat de gebruikersfunctie een doel voor het neerzetten is, overschrijft u de methoden waarmee de gebruikersfunctie een doel voor het neerzetten kan zijn en verwerkt u de gegevens die erop worden neergezet.

Het gebruikersbeheer inschakelen als een doel voor neerzetten

  1. Open Circle.xaml.

  2. Voeg in de openingstag UserControl de AllowDrop eigenschap toe en stel deze in op true.

    <UserControl x:Class="DragDropWalkthrough.Circle"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300"
                 AllowDrop="True">
    

De OnDrop methode wordt aangeroepen wanneer de AllowDrop eigenschap is ingesteld op true en gegevens uit de sleepbron worden verwijderd op het gebruikersbesturingselement Circle. In deze methode verwerkt u de gegevens die zijn verwijderd en past u de gegevens toe op de cirkel.

De verwijderde gegevens verwerken

  1. Open Circle.xaml.cs of Circle.xaml.vb.

  2. Voeg de volgende OnDrop overschrijving toe om de afhandeling van de klasse voor de Drop gebeurtenis te verzorgen.

    protected override void OnDrop(DragEventArgs e)
    {
        base.OnDrop(e);
    
        // If the DataObject contains string data, extract it.
        if (e.Data.GetDataPresent(DataFormats.StringFormat))
        {
            string dataString = (string)e.Data.GetData(DataFormats.StringFormat);
    
            // If the string can be converted into a Brush,
            // convert it and apply it to the ellipse.
            BrushConverter converter = new BrushConverter();
            if (converter.IsValid(dataString))
            {
                Brush newFill = (Brush)converter.ConvertFromString(dataString);
                circleUI.Fill = newFill;
    
                // Set Effects to notify the drag source what effect
                // the drag-and-drop operation had.
                // (Copy if CTRL is pressed; otherwise, move.)
                if (e.KeyStates.HasFlag(DragDropKeyStates.ControlKey))
                {
                    e.Effects = DragDropEffects.Copy;
                }
                else
                {
                    e.Effects = DragDropEffects.Move;
                }
            }
        }
        e.Handled = true;
    }
    
    Protected Overrides Sub OnDrop(ByVal e As System.Windows.DragEventArgs)
        MyBase.OnDrop(e)
        ' If the DataObject contains string data, extract it.
        If e.Data.GetDataPresent(DataFormats.StringFormat) Then
            Dim dataString As String = e.Data.GetData(DataFormats.StringFormat)
    
            ' If the string can be converted into a Brush, 
            ' convert it and apply it to the ellipse.
            Dim converter As New BrushConverter
            If converter.IsValid(dataString) Then
                Dim newFill As Brush = converter.ConvertFromString(dataString)
                circleUI.Fill = newFill
    
                ' Set Effects to notify the drag source what effect
                ' the drag-and-drop operation had.
                ' (Copy if CTRL is pressed; otherwise, move.)
                If e.KeyStates.HasFlag(DragDropKeyStates.ControlKey) Then
                    e.Effects = DragDropEffects.Copy
                Else
                    e.Effects = DragDropEffects.Move
                End If
            End If
        End If
        e.Handled = True
    End Sub
    

    Met deze OnDrop overschrijving worden de volgende taken uitgevoerd:

    • Gebruikt de GetDataPresent methode om te controleren of de gesleepte gegevens een tekenreeksobject bevatten.

    • Gebruikt de GetData methode om de tekenreeksgegevens te extraheren als deze aanwezig zijn.

    • Gebruikt een BrushConverter om de tekenreeks te converteren naar een Brush.

    • Als de conversie succesvol is, wordt het penseel toegepast op de Fill van de Ellipse die de gebruikersinterface van het Circle-besturingselement biedt.

    • Markeert de Drop gebeurtenis als verwerkt. U moet het drop-event markeren als verwerkt, zodat andere elementen die deze gebeurtenis ontvangen, weten dat de Circle-gebruikerscontrole deze heeft verwerkt.

  3. Druk op F5- om de toepassing te bouwen en uit te voeren.

  4. Selecteer de tekst green in de TextBox.

  5. Sleep de tekst naar een cirkelvormig controle-element en laat het los. De cirkel verandert van blauw in groen.

    Een tekenreeks converteren naar een kwast

  6. Typ de tekst green in de TextBox.

  7. Selecteer de tekst gre in de TextBox.

  8. Sleep het naar een cirkel besturingselement en zet het neer. U ziet dat de cursor verandert om aan te geven dat de neergang is toegestaan, maar dat de kleur van de cirkel niet verandert omdat gre dit geen geldige kleur is.

  9. Sleep vanuit het groene besturingselement Cirkel en zet neer op het blauwe besturingselement Cirkel. De cirkel verandert van blauw in groen. Let op dat welke cursor wordt getoond, afhangt van of de TextBox of de cirkel de sleepbron is.

Het instellen van de AllowDrop eigenschap op true en het verwerken van de neergezette gegevens is alles wat nodig is om een element als een doel voor neerzetten in te schakelen. Als u echter een betere gebruikerservaring wilt bieden, moet u ook de DragEnter, DragLeaveen DragOver gebeurtenissen afhandelen. In deze gebeurtenissen kunt u controles uitvoeren en aanvullende feedback geven aan de gebruiker voordat de gegevens worden verwijderd.

Wanneer gegevens over het gebruikersbesturingselement Circle worden gesleept, moet het besturingselement de sleepbron informeren of deze de gegevens kan verwerken die worden gesleept. Als het besturingselement niet weet hoe de gegevens moeten worden verwerkt, moet deze de daling weigeren. Hiervoor gaat u de DragOver gebeurtenis afhandelen en de Effects eigenschap instellen.

Controleren of de gegevensuitval is toegestaan

  1. Open Circle.xaml.cs of Circle.xaml.vb.

  2. Voeg de volgende OnDragOver overschrijving toe om de afhandeling van de klasse voor de DragOver gebeurtenis te verzorgen.

    protected override void OnDragOver(DragEventArgs e)
    {
        base.OnDragOver(e);
        e.Effects = DragDropEffects.None;
    
        // If the DataObject contains string data, extract it.
        if (e.Data.GetDataPresent(DataFormats.StringFormat))
        {
            string dataString = (string)e.Data.GetData(DataFormats.StringFormat);
    
            // If the string can be converted into a Brush, allow copying or moving.
            BrushConverter converter = new BrushConverter();
            if (converter.IsValid(dataString))
            {
                // Set Effects to notify the drag source what effect
                // the drag-and-drop operation will have. These values are
                // used by the drag source's GiveFeedback event handler.
                // (Copy if CTRL is pressed; otherwise, move.)
                if (e.KeyStates.HasFlag(DragDropKeyStates.ControlKey))
                {
                    e.Effects = DragDropEffects.Copy;
                }
                else
                {
                    e.Effects = DragDropEffects.Move;
                }
            }
        }
        e.Handled = true;
    }
    
    Protected Overrides Sub OnDragOver(ByVal e As System.Windows.DragEventArgs)
        MyBase.OnDragOver(e)
        e.Effects = DragDropEffects.None
    
        ' If the DataObject contains string data, extract it.
        If e.Data.GetDataPresent(DataFormats.StringFormat) Then
            Dim dataString As String = e.Data.GetData(DataFormats.StringFormat)
    
            ' If the string can be converted into a Brush, allow copying or moving.
            Dim converter As New BrushConverter
            If converter.IsValid(dataString) Then
                ' Set Effects to notify the drag source what effect
                ' the drag-and-drop operation will have. These values are 
                ' used by the drag source's GiveFeedback event handler.
                ' (Copy if CTRL is pressed; otherwise, move.)
                If e.KeyStates.HasFlag(DragDropKeyStates.ControlKey) Then
                    e.Effects = DragDropEffects.Copy
                Else
                    e.Effects = DragDropEffects.Move
                End If
            End If
        End If
        e.Handled = True
    End Sub
    

    Met deze OnDragOver overschrijving worden de volgende taken uitgevoerd:

    • Hiermee stelt u de Effects eigenschap in op None.

    • Voert dezelfde controles uit die in de OnDrop methode worden uitgevoerd om te bepalen of het gebruikersbeheer van Circle de gesleepte gegevens kan verwerken.

    • Als het gebruikersbesturingselement de gegevens kan verwerken, stelt u de Effects eigenschap in op Copy of Move.

  3. Druk op F5- om de toepassing te bouwen en uit te voeren.

  4. Selecteer de tekst gre in de TextBox.

  5. Sleep de tekst naar het cirkelbesturingselement. U ziet dat de cursor nu verandert om aan te geven dat de neerhaling niet is toegestaan omdat gre dit geen geldige kleur is.

U kunt de gebruikerservaring verder verbeteren door een voorbeeld van de drop-bewerking toe te passen. Voor het gebruikersbeheer van Circle overschrijft u de OnDragEnter en OnDragLeave methoden. Wanneer de gegevens over het besturingselement worden gesleept, wordt de huidige achtergrond Fill opgeslagen in een plaatsvervangende variabele. De tekenreeks wordt vervolgens geconverteerd naar een penseel en toegepast op de gebruikersinterface Ellipse die de cirkel biedt. Als de gegevens uit de cirkel worden gesleept zonder te worden verwijderd, wordt de oorspronkelijke Fill waarde opnieuw toegepast op de cirkel.

Bekijk een voorbeeld van de effecten van de slepen-en-neerzetten-bewerking.

  1. Open Circle.xaml.cs of Circle.xaml.vb.

  2. Declareer in de klasse Circle een persoonlijke Brush variabele met de naam _previousFill en initialiseer deze naar null.

    public partial class Circle : UserControl
    {
        private Brush _previousFill = null;
    
    Public Class Circle
        Private _previousFill As Brush = Nothing
    
  3. Voeg de volgende OnDragEnter overschrijving toe om de afhandeling van de klasse voor de DragEnter gebeurtenis te verzorgen.

    protected override void OnDragEnter(DragEventArgs e)
    {
        base.OnDragEnter(e);
        // Save the current Fill brush so that you can revert back to this value in DragLeave.
        _previousFill = circleUI.Fill;
    
        // If the DataObject contains string data, extract it.
        if (e.Data.GetDataPresent(DataFormats.StringFormat))
        {
            string dataString = (string)e.Data.GetData(DataFormats.StringFormat);
    
            // If the string can be converted into a Brush, convert it.
            BrushConverter converter = new BrushConverter();
            if (converter.IsValid(dataString))
            {
                Brush newFill = (Brush)converter.ConvertFromString(dataString.ToString());
                circleUI.Fill = newFill;
            }
        }
    }
    
    Protected Overrides Sub OnDragEnter(ByVal e As System.Windows.DragEventArgs)
        MyBase.OnDragEnter(e)
        _previousFill = circleUI.Fill
    
        ' If the DataObject contains string data, extract it.
        If e.Data.GetDataPresent(DataFormats.StringFormat) Then
            Dim dataString As String = e.Data.GetData(DataFormats.StringFormat)
    
            ' If the string can be converted into a Brush, convert it.
            Dim converter As New BrushConverter
            If converter.IsValid(dataString) Then
                Dim newFill As Brush = converter.ConvertFromString(dataString)
                circleUI.Fill = newFill
            End If
        End If
        e.Handled = True
    End Sub
    

    Met deze OnDragEnter overschrijving worden de volgende taken uitgevoerd:

    • Hiermee wordt de Fill eigenschap van de Ellipse_previousFill variabele opgeslagen.

    • Voert dezelfde controles uit die in de OnDrop methode worden uitgevoerd om te bepalen of de gegevens kunnen worden geconverteerd naar een Brush.

    • Als de gegevens worden geconverteerd naar een geldige Brush, wordt het toegepast op de Fill van de Ellipse.

  4. Voeg de volgende OnDragLeave overschrijving toe om de afhandeling van de klasse voor de DragLeave gebeurtenis te verzorgen.

    protected override void OnDragLeave(DragEventArgs e)
    {
        base.OnDragLeave(e);
        // Undo the preview that was applied in OnDragEnter.
        circleUI.Fill = _previousFill;
    }
    
    Protected Overrides Sub OnDragLeave(ByVal e As System.Windows.DragEventArgs)
        MyBase.OnDragLeave(e)
        ' Undo the preview that was applied in OnDragEnter.
        circleUI.Fill = _previousFill
    End Sub
    

    Met deze OnDragLeave overschrijving worden de volgende taken uitgevoerd:

    • Hiermee wordt de Brush opgeslagen in de _previousFill variabele toegepast op de FillEllipse gebruikersinterface van het besturingselement Circle-gebruiker.
  5. Druk op F5- om de toepassing te bouwen en uit te voeren.

  6. Selecteer de tekst green in de TextBox.

  7. Sleep de tekst over een cirkel besturingselement zonder deze neer te laten vallen. De cirkel verandert van blauw in groen.

    Bekijk een voorbeeld van de effecten van een slepen-en-neerzetten-bewerking

  8. Sleep de tekst weg van het besturingselement Cirkel. De cirkel verandert van groen terug in blauw.

Een deelvenster inschakelen voor het ontvangen van verwijderde gegevens

In deze sectie schakelt u de panelen in die als host fungeren voor de besturingselementen van de Circle-gebruiker om te fungeren als dropdoelen voor gesleepte cirkelgegevens. U implementeert code waarmee u een cirkel van het ene deelvenster naar het andere kunt verplaatsen, of een kopie van een cirkelcontroles maakt door de Ctrl-toets ingedrukt te houden terwijl u een cirkel sleept en neerzet.

  1. Open MainWindow.xaml.

  2. Zoals wordt weergegeven in de volgende XAML, voeg in elk van de StackPanel elementen handlers toe voor de DragOver en Drop gebeurtenissen. Geef de gebeurtenis-handler DragOver de naam panel_DragOver en geef de gebeurtenis-handler Drop de naam panel_Drop.

    Standaard zijn de panelen geen sleepdoelen. Als u ze wilt inschakelen, voegt u de AllowDrop eigenschap toe aan beide panelen en stelt u de waarde in op true.

    <StackPanel Grid.Column="0"
                Background="Beige"
                AllowDrop="True"
                DragOver="panel_DragOver"
                Drop="panel_Drop">
        <TextBox Width="Auto" Margin="2"
                 Text="green"/>
        <local:Circle Margin="2" />
        <local:Circle Margin="2" />
    </StackPanel>
    <StackPanel Grid.Column="1"
                Background="Bisque"
                AllowDrop="True"
                DragOver="panel_DragOver"
                Drop="panel_Drop">
    </StackPanel>
    
  3. Open MainWindows.xaml.cs of MainWindow.xaml.vb.

  4. Voeg de volgende code toe voor de DragOver gebeurtenis-handler.

    private void panel_DragOver(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent("Object"))
        {
            // These Effects values are used in the drag source's
            // GiveFeedback event handler to determine which cursor to display.
            if (e.KeyStates == DragDropKeyStates.ControlKey)
            {
                e.Effects = DragDropEffects.Copy;
            }
            else
            {
                e.Effects = DragDropEffects.Move;
            }
        }
    }
    
    Private Sub panel_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs)
        If e.Data.GetDataPresent("Object") Then
            ' These Effects values are used in the drag source's
            ' GiveFeedback event handler to determine which cursor to display.
            If e.KeyStates = DragDropKeyStates.ControlKey Then
                e.Effects = DragDropEffects.Copy
            Else
                e.Effects = DragDropEffects.Move
            End If
        End If
    End Sub
    

    Deze DragOver gebeurtenis-handler voert de volgende taken uit:

    • Controleert of de gesleepte gegevens de objectgegevens bevatten die zijn verpakt in het DataObject besturingselement Circle-gebruiker en worden doorgegeven aan de aanroep.DoDragDrop

    • Als de objectgegevens aanwezig zijn, controleert u of de Ctrl-toets wordt ingedrukt.

    • Als de Ctrl-toets wordt ingedrukt, stelt u de Effects eigenschap in op Copy. Anders stelt u de Effects eigenschap in op Move.

  5. Voeg de volgende code toe voor de Drop gebeurtenis-handler.

    private void panel_Drop(object sender, DragEventArgs e)
    {
        // If an element in the panel has already handled the drop,
        // the panel should not also handle it.
        if (e.Handled == false)
        {
            Panel _panel = (Panel)sender;
            UIElement _element = (UIElement)e.Data.GetData("Object");
    
            if (_panel != null && _element != null)
            {
                // Get the panel that the element currently belongs to,
                // then remove it from that panel and add it the Children of
                // the panel that its been dropped on.
                Panel _parent = (Panel)VisualTreeHelper.GetParent(_element);
    
                if (_parent != null)
                {
                    if (e.KeyStates == DragDropKeyStates.ControlKey &&
                        e.AllowedEffects.HasFlag(DragDropEffects.Copy))
                    {
                        Circle _circle = new Circle((Circle)_element);
                        _panel.Children.Add(_circle);
                        // set the value to return to the DoDragDrop call
                        e.Effects = DragDropEffects.Copy;
                    }
                    else if (e.AllowedEffects.HasFlag(DragDropEffects.Move))
                    {
                        _parent.Children.Remove(_element);
                        _panel.Children.Add(_element);
                        // set the value to return to the DoDragDrop call
                        e.Effects = DragDropEffects.Move;
                    }
                }
            }
        }
    }
    
    Private Sub panel_Drop(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs)
        ' If an element in the panel has already handled the drop,
        ' the panel should not also handle it.
        If e.Handled = False Then
            Dim _panel As Panel = sender
            Dim _element As UIElement = e.Data.GetData("Object")
    
            If _panel IsNot Nothing And _element IsNot Nothing Then
                ' Get the panel that the element currently belongs to,
                ' then remove it from that panel and add it the Children of
                ' the panel that its been dropped on.
    
                Dim _parent As Panel = VisualTreeHelper.GetParent(_element)
                If _parent IsNot Nothing Then
                    If e.KeyStates = DragDropKeyStates.ControlKey And _
                        e.AllowedEffects.HasFlag(DragDropEffects.Copy) Then
                        Dim _circle As New Circle(_element)
                        _panel.Children.Add(_circle)
                        ' set the value to return to the DoDragDrop call
                        e.Effects = DragDropEffects.Copy
                    ElseIf e.AllowedEffects.HasFlag(DragDropEffects.Move) Then
                        _parent.Children.Remove(_element)
                        _panel.Children.Add(_element)
                        ' set the value to return to the DoDragDrop call
                        e.Effects = DragDropEffects.Move
                    End If
                End If
            End If
        End If
    End Sub
    

    Deze Drop gebeurtenis-handler voert de volgende taken uit:

    • Controleert of de Drop gebeurtenis al is verwerkt. Als een cirkel bijvoorbeeld op een andere cirkel wordt geplaatst, die de Drop gebeurtenis afhandelt, wilt u niet dat het deelvenster dat de cirkels bevat deze gebeurtenis ook afhandelt.

    • Als de Drop gebeurtenis niet wordt verwerkt, controleert u of de Ctrl-toets wordt ingedrukt.

    • Als de Ctrl-toets wordt ingedrukt wanneer het Drop gebeurt, maakt u een kopie van het besturingselement Cirkel en voegt u deze toe aan de Children verzameling van de StackPanel.

    • Als de Ctrl-toets niet wordt ingedrukt, verplaatst u de cirkel van de verzameling van het Children bovenliggende deelvenster naar de Children verzameling van het deelvenster waarop deze is neergezet.

    • Hiermee stelt u de Effects eigenschap in om de DoDragDrop methode te informeren of er een verplaatsings- of kopieerbewerking is uitgevoerd.

  6. Druk op F5- om de toepassing te bouwen en uit te voeren.

  7. Selecteer de tekst green uit de TextBox.

  8. Sleep de tekst naar een bedieningselement in cirkelvorm en laat het los.

  9. Sleep een cirkel-besturingselement van het linkerdeelvenster naar het rechterdeelvenster en zet het neer. De cirkel wordt verwijderd uit de Children verzameling van het linkerpaneel en toegevoegd aan de verzameling Onderliggende items van het rechterdeelvenster.

  10. Sleep een cirkel besturingselement van het deelvenster naar het andere deelvenster en zet het neer terwijl u op Ctrl drukt. De cirkel wordt gekopieerd en de kopie wordt toegevoegd aan de Children collectie van het ontvangende paneel.

    Een cirkel slepen terwijl u op ctrl drukt

Zie ook