Aracılığıyla paylaş


Kılavuz: Kullanıcı Denetiminde Sürükle ve Bırak'ı Etkinleştirme

Bu kılavuzda, Windows Presentation Foundation'da (WPF) sürükle ve bırak veri aktarımına katılabilen özel bir kullanıcı denetiminin nasıl oluşturulacağı gösterilmektedir.

Bu kılavuzda, daire şeklini temsil eden özel bir WPF UserControl oluşturacaksınız. Sürükle ve bırak yoluyla veri aktarımını etkinleştirmek için denetimde işlevsellik uygulayacaksınız. Örneğin, bir Daire denetiminden diğerine sürüklerseniz, Dolgu rengi verileri kaynak Daire'den hedefe kopyalanır. Daire denetiminden öğesine TextBoxsürüklerseniz, Dolgu renginin dize gösterimi öğesine TextBoxkopyalanır. Ayrıca sürükle ve bırak işlevini test etmek için iki panel denetimi ve bir TextBox içeren küçük bir uygulama oluşturacaksınız. Panellerin bırakılan daire verilerini işlemesine olanak tanıyan bir kod yazacaksınız. Bu kod, daireleri bir panelin alt nesneler koleksiyonundan diğerine taşımanıza veya kopyalamanıza olanak tanır.

Bu kılavuzda aşağıdaki görevler gösterilmektedir:

  • Özel bir kullanıcı denetimi oluşturun.

  • Kullanıcı denetimini sürükleme kaynağı olarak etkinleştirin.

  • Kullanıcı denetimini bırakma hedefi olarak etkinleştirin.

  • Kullanıcı denetiminden bırakılan verileri almak için paneli etkinleştirin.

Önkoşullar

Bu kılavuzu tamamlamak için Visual Studio'ya ihtiyacınız vardır.

Uygulama Projesi Oluşturma

Bu bölümde, iki panel ve TextBoxbir içeren bir ana sayfa içeren uygulama altyapısını oluşturacaksınız.

  1. Visual Basic veya Visual C# içinde DragDropExampleadlı yeni bir WPF Uygulaması projesi oluşturun. Daha fazla bilgi için bkz. Kılavuz: İlk WPF masaüstü uygulamam.

  2. MainWindow.xaml dosyasını açın.

  3. Açma ve kapatma Grid etiketleri arasına aşağıdaki işaretlemeyi ekleyin.

    Bu işaretleme, test uygulaması için kullanıcı arabirimini oluşturur.

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

Projeye Yeni Kullanıcı Denetimi Ekleme

Bu bölümde projeye yeni bir kullanıcı denetimi ekleyeceğiz.

  1. Proje menüsünde Kullanıcı Denetimi Ekle'yi seçin.

  2. Yeni Öğe Ekle iletişim kutusunda, adı olarak Circle.xamldeğiştirin ve Ekle'ye tıklayın.

    Circle.xaml ve onun kod-arkası projeye eklenir.

  3. Circle.xaml dosyasını açın.

    Bu dosya, kullanıcı denetiminin kullanıcı arabirimi öğelerini içerir.

  4. Kullanıcı arabirimi olarak mavi daire içeren basit bir kullanıcı denetimi oluşturmak için köke Grid aşağıdaki işaretlemeyi ekleyin.

    <Ellipse x:Name="circleUI" 
             Height="100" Width="100"
             Fill="Blue" />
    
  5. Circle.xaml.cs veya Circle.xaml.vb açın.

  6. C# dilinde aşağıdaki kodu parametresiz oluşturucunun arkasına ekleyerek bir kopya oluşturucu oluşturun. Visual Basic'te, hem parametresiz oluşturucu hem de kopya oluşturucu oluşturmak için aşağıdaki kodu ekleyin.

    Kullanıcı denetiminin kopyalanmasını sağlamak için arka planda kod dosyasına bir kopya oluşturucu yöntemi eklersiniz. Basitleştirilmiş Circle kullanıcı denetiminde, yalnızca Dolgu'yu ve kullanıcı denetiminin boyutunu kopyalayacaksınız.

    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
    

Kullanıcı denetimini ana pencereye ekleme

  1. MainWindow.xaml dosyasını açın.

  2. Geçerli uygulamaya bir XML ad alanı başvurusu oluşturmak için aşağıdaki XAML'yi açılış Window etiketine ekleyin.

    xmlns:local="clr-namespace:DragDropExample"
    
  3. İlk StackPanelpanelde Circle kullanıcı denetiminin iki örneğini oluşturmak için aşağıdaki XAML'yi ekleyin.

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

    Panelin tam XAML'i aşağıdaki gibi görünür.

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

Kullanıcı Kontrolünde Sürükleme Kaynağı Olaylarını Uygulama

Bu bölümde OnMouseMove yöntemini geçersiz kılacak ve sürükle ve bırak işlemini başlatacaksınız.

Eğer bir sürükleme başlatılırsa (fare düğmesine basılır ve fare taşınırsa), aktarılacak verileri bir DataObject içine paketleyeceksiniz. Bu durumda, Daire denetimi üç veri öğesini paketler; Dolgu renginin dize gösterimi, yüksekliğinin çift gösterimi ve kendisinin bir kopyası.

Sürükle ve bırak işlemini başlatmak için

  1. Circle.xaml.cs veya Circle.xaml.vb açın.

  2. Aşağıdaki OnMouseMove geçersiz kılmayı, MouseMove olayı için sınıf işleme sağlamak amacıyla ekleyin.

    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
    

    Bu OnMouseMove geçersiz kılma aşağıdaki görevleri gerçekleştirir:

    • Fare hareket ederken sol fare düğmesine basılıp basılmadığını denetler.

    • Circle verilerini DataObject içine paketler. Bu durumda, Daire denetimi üç veri öğesini paketler; Dolgu renginin dize gösterimi, yüksekliğinin çift gösterimi ve kendisinin bir kopyası.

    • Sürükle ve bırak işlemini başlatmak için statik DragDrop.DoDragDrop yöntemi çağırır. metoduna aşağıdaki üç parametreyi DoDragDrop geçirirsiniz.

      • dragSource – Bu denetime referans.

      • data – Önceki kodda oluşturulan DataObject.

      • allowedEffects – İzin verilen sürükle ve bırak işlemleri, Copy veya Move'dir.

  3. Uygulamayı derlemek ve çalıştırmak için F5 basın.

  4. Daire kontrollerinden birine tıklayın ve panellerin, diğer Daire kontrolünün ve TextBox öğesinin üzerine sürükleyin. TextBox üzerine sürüklerken, imleç taşımayı göstermek için değişir.

  5. Daireyi TextBoxüzerine sürüklerken Ctrl tuşuna basın. İmlecin kopyayı gösterecek şekilde nasıl değiştiğine dikkat edin.

  6. Daireyi TextBox üzerine sürükleyip bırakın. Dairenin dolgu renginin dize gösterimi TextBox sonuna eklenir.

    Dairenin dolgu renginin dize gösterimi

Varsayılan olarak, sürükle ve bırak işlemi sırasında imleç, verileri bırakmanın hangi etkiyi oluşturacağını belirtmek için değişir. Kullanıcıya verilen geri bildirimi, GiveFeedback olayını işleyerek ve farklı bir imleç ayarlayarak özelleştirebilirsiniz.

Kullanıcıya geri bildirimde bulunmak

  1. Circle.xaml.cs veya Circle.xaml.vb açın.

  2. Aşağıdaki OnGiveFeedback geçersiz kılmayı, GiveFeedback olayı için sınıf işleme sağlamak amacıyla ekleyin.

    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
    

    Bu OnGiveFeedback geçersiz kılma aşağıdaki görevleri gerçekleştirir:

    • Bırakma hedefinin olay işleyicisinde ayarlanan EffectsDragOver değerlerini denetler.

    • Değere Effects göre özel bir imleç ayarlar. İmleç, kullanıcıya verileri bırakmanın ne gibi bir etkisi olacağı hakkında görsel geri bildirim sağlamak için tasarlanmıştır.

  3. Uygulamayı derlemek ve çalıştırmak için F5 basın.

  4. Daire denetimlerinden birini panellerin, diğer dairenin ve TextBox öğesinin üzerine sürükleyin. İmleçlerin artık geçersiz kılmada OnGiveFeedback belirttiğiniz özel imleçler olduğuna dikkat edin.

    Özel imleçlerle sürükleyip bırakma

  5. Metni green içinden TextBox seçin.

  6. green Metni Daire kontrolüne sürükleyin. Sürükle ve bırak işleminin etkilerini göstermek için varsayılan imleçlerin gösterildiğine dikkat edin. Geri bildirim imleci her zaman sürükleme kaynağı tarafından ayarlanır.

Kullanıcı Denetiminde Bırakma Hedefi Olaylarını Uygulamak

Bu bölümde, kullanıcı denetiminin bir bırakma hedefi olduğunu belirtecek, kullanıcı denetiminin bırakma hedefi olmasını sağlayan yöntemleri geçersiz kılacak ve üzerine bırakılan verileri işleyeceksiniz.

Kullanıcı denetiminin bırakma hedefi olmasını sağlamak için

  1. Circle.xaml dosyasını açın.

  2. Açılış UserControl etiketinde özelliğini ekleyin AllowDrop ve olarak trueayarlayın.

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

OnDrop özelliği olarak ayarlandığında AllowDrop ve sürükleme kaynağındaki veriler Circle kullanıcı denetimine bırakıldığında true yöntemi çağrılır. Bu yöntemde bırakılan verileri işleyecek ve circle'a uygulayacaksınız.

Bırakılan verileri işlemek için

  1. Circle.xaml.cs veya Circle.xaml.vb açın.

  2. Aşağıdaki OnDrop geçersiz kılmayı, Drop olayı için sınıf işleme sağlamak amacıyla ekleyin.

    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
    

    Bu OnDrop geçersiz kılma aşağıdaki görevleri gerçekleştirir:

    • Sürüklenen GetDataPresent verilerin dize nesnesi içerip içermediğini denetlemek için yöntemini kullanır.

    • Dize verileri varsa ayıklamak için GetData yöntemini kullanır.

    • dizesini öğesine dönüştürmeyi denemek için kullanır BrushConverterBrush.

    • Dönüştürme başarılı olursa, fırçayı FillEllipse Daire denetiminin kullanıcı arabirimini sağlayan öğesine uygular.

    • Drop olayını işlenmiş olarak işaretler. Bırakma olayını işlenmiş olarak işaretlemeniz gerekir ki bu olayı alan diğer öğeler Circle kullanıcı kontrolünün bunu işlediğini bilsin.

  3. Uygulamayı derlemek ve çalıştırmak için F5 basın.

  4. green içindeki TextBox metni seçin.

  5. Metni bir Daire kontrolüne sürükleyip bırakın. Daire maviden yeşile dönüşür.

    Veriyi bir fırçaya dönüştür

  6. green içindeki TextBox metni yazın.

  7. gre içindeki TextBox metni seçin.

  8. Onu daire kontrolüne sürükleyip bırakın. Şunu fark edin: İmleç, bırakma işlemine izin verildiğini gösterecek şekilde değişir, ancak gre geçerli bir renk olmadığından, Dairenin rengi değişmez.

  9. Yeşil Daire denetiminden sürükleyin ve mavi Daire denetimine bırakın. Daire maviden yeşile dönüşür. Gösterilen imlecin, sürükleme kaynağı olarak TextBox veya Dairenin seçilmiş olup olmamasına bağlı olduğunu fark edin.

AllowDrop özelliğini true olarak ayarlamak ve bırakılan verileri işlemesi, bir öğenin bırakma hedefi olabilmesi için yeterlidir. Ancak, daha iyi bir kullanıcı deneyimi sağlamak için DragEnter, DragLeave ve DragOver olaylarını işlemeniz gerekir. Bu olaylarda, denetimler gerçekleştirebilir ve veriler bırakılmadan önce kullanıcıya ek geri bildirim sağlayabilirsiniz.

Veriler Circle kullanıcı denetiminin üzerine sürüklendiğinde, denetim sürüklenen verileri işleyip işleyemeyeceğini sürükleme kaynağına bildirmelidir. Denetim verilerin nasıl işlenip işlenmediğini bilmiyorsa bırakma işlemini reddetmelidir. Bunu yapmak için DragOver olayını işleyecek ve Effects özelliğini ayarlayacaksınız.

Veri bırakma işlemine izin verildiğini doğrulamak için

  1. Circle.xaml.cs veya Circle.xaml.vb açın.

  2. Aşağıdaki OnDragOver geçersiz kılmayı, DragOver olayı için sınıf işleme sağlamak amacıyla ekleyin.

    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
    

    Bu OnDragOver geçersiz kılma aşağıdaki görevleri gerçekleştirir:

    • Effects özelliğini None olarak ayarlar.

    • Circle kullanıcı denetiminin sürüklenen verileri işleyip işleyemeyeceğini belirlemek için yönteminde OnDrop gerçekleştirilen denetimlerin aynısını gerçekleştirir.

    • Eğer kullanıcı denetimi verileri işleyebilirse, Effects özelliğini Copy veya Move olarak ayarlar.

  3. Uygulamayı derlemek ve çalıştırmak için F5 basın.

  4. gre içindeki TextBox metni seçin.

  5. Metni Daire kontrolüne sürükleyin. İmlecin artık geçerli bir renk olmadığından bırakma işlemine izin verilmediğini gre gösterecek şekilde değiştiğine dikkat edin.

Bırakma işleminin önizlemesini uygulayarak kullanıcı deneyimini daha da geliştirebilirsiniz. Circle kullanıcı denetimi için OnDragEnter ve OnDragLeave yöntemlerini geçersiz kılacaksınız. Veriler denetimin üzerine sürüklendiğinde, geçerli arka plan Fill bir yer tutucu değişkene kaydedilir. Dize, daha sonra bir fırçaya dönüştürülür ve Dairenin kullanıcı arabirimini sağlayan Ellipse öğesine uygulanır. Veriler Daire'nin dışına bırakılmadan sürüklenirse, özgün Fill değer yeniden Daireye uygulanır.

Sürükle ve bırak işleminin etkilerini önizlemek için

  1. Circle.xaml.cs veya Circle.xaml.vb açın.

  2. Circle sınıfında, Brush adlı özel bir _previousFill değişken bildirin ve null ile başlatın.

    public partial class Circle : UserControl
    {
        private Brush _previousFill = null;
    
    Public Class Circle
        Private _previousFill As Brush = Nothing
    
  3. Aşağıdaki OnDragEnter geçersiz kılmayı, DragEnter olayı için sınıf işleme sağlamak amacıyla ekleyin.

    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
    

    Bu OnDragEnter geçersiz kılma aşağıdaki görevleri gerçekleştirir:

    • Fill öğesinin Ellipse özelliğini _previousFill değişkenine kaydeder.

    • Yönteminde OnDrop gerçekleştirilen denetimlerin aynısını gerçekleştirerek verilerin bir Brush'e dönüştürülip dönüştürülemeyeceğini belirler.

    • Veriler geçerli Brushbir öğesine dönüştürülürse, verileri FillEllipseöğesine uygular.

  4. Aşağıdaki OnDragLeave geçersiz kılmayı, DragLeave olayı için sınıf işleme sağlamak amacıyla ekleyin.

    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
    

    Bu OnDragLeave geçersiz kılma aşağıdaki görevleri gerçekleştirir:

    • Circle kullanıcı denetiminin kullanıcı arabirimini sağlayan Brush'ün _previousFill'sine, Fill değişkenine kaydedilen Ellipse öğesi uygulanır.
  5. Uygulamayı derlemek ve çalıştırmak için F5 basın.

  6. green içindeki TextBox metni seçin.

  7. Metni bırakmadan Daire denetiminin üzerine sürükleyin. Daire maviden yeşile dönüşür.

    Sürükle ve bırak işleminin etkilerini önizleme

  8. Metni Daire kontrolünden uzağa sürükleyin. Daire yeşilden tekrar maviye döner.

Bırakılan Verileri Almak için Paneli Etkinleştir

Bu bölümde, Circle kullanıcı kontrollerini barındıran panellerin, sürüklenen Circle verilerini bırakma hedefleri olarak işlev görmesini sağlarsınız. Daireyi bir panelden diğerine taşımanıza veya daireyi sürükleyip bırakırken Ctrl tuşunu basılı tutarak Daire denetiminin bir kopyasını oluşturmanıza olanak tanıyan kodu uygulayacaksınız.

  1. MainWindow.xaml dosyasını açın.

  2. Aşağıdaki XAML'de gösterildiği gibi, her bir StackPanel denetiminde, DragOver ve Drop olayları için işleyiciler ekleyin. Olay işleyicisini DragOver olarak adlandırın, panel_DragOver ve Drop olay işleyicisini panel_Drop olarak adlandırın.

    Varsayılan olarak, paneller hedef bırakmaz. Bunları etkinleştirmek için özelliğini her iki panele de ekleyin AllowDrop ve değerini olarak trueayarlayın.

    <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. MainWindows.xaml.cs veya MainWindow.xaml.vb açın.

  4. Olay işleyicisi DragOver için aşağıdaki kodu ekleyin.

    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
    

    Bu DragOver olay işleyicisi aşağıdaki görevleri gerçekleştirir:

    • Sürüklenen verilerin, Circle kullanıcı denetimi tarafından DataObject içinde paketlenen ve DoDragDrop çağrısında iletilen "Nesne" verilerini içerip içermediğini denetler.

    • "Nesne" verileri varsa , Ctrl tuşuna basılıp basılmadığını denetler.

    • Ctrl tuşuna basıldığında, Effects özelliği Copy olarak ayarlanır. Aksi takdirde, Effects özelliğini Move olarak ayarlayın.

  5. Olay işleyicisi Drop için aşağıdaki kodu ekleyin.

    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
    

    Bu Drop olay işleyicisi aşağıdaki görevleri gerçekleştirir:

    • Olayın daha önce işlenip işlenmediğini Drop denetler. Örneğin, bir Daire başka bir Daire üzerine Drop olayını yönetmesi için bırakıldığında, Daireyi barındıran panelin de bu olayı yönetmesini istemezsiniz.

    • `Drop` olay işlenmezse, `Ctrl` tuşuna basılıp basılmadığını denetler.

    • gerçekleştiğinde Drop tuşuna basılırsa, Daire denetiminin bir kopyasını alır ve Children koleksiyonuna StackPanel ekler.

    • Ctrl tuşuna basılmazsa, Daireyi üst panelinin Children koleksiyonundan bırakıldığı panelin Children koleksiyonuna taşır.

    • Effects Bir taşıma veya kopyalama işleminin gerçekleştirilip gerçekleştirilmediğini yöntemine DoDragDrop bildirmek için özelliğini ayarlar.

  6. Uygulamayı derlemek ve çalıştırmak için F5 basın.

  7. Metni green içinden TextBox seçin.

  8. Metni daire kontrolünün üzerine sürükleyip bırakın.

  9. Sol panelden bir Daire denetimini sağ panele sürükleyip bırakın. Daire, sol panelin Children koleksiyonundan kaldırılır ve sağ panelin Çocuklar koleksiyonuna eklenir.

  10. Bir Daire denetimini, içinde olduğu panelden diğer panele sürükleyin ve Ctrl tuşuna basarken bırakın. Daire kopyalanır ve kopya alıcı panelin Children koleksiyonuna eklenir.

    CTRL tuşuna basarken Daire sürükleme

Ayrıca bakınız