İzlenecek yol: Kullanıcı Denetiminde Sürükleme ve Bırakmayı Etkinleştirme

Bu izlenecek yol, ' de sürükle ve bırak veri aktarımına katılabilen özel bir kullanıcı denetiminin nasıl oluşturulduğunu gösterir Windows Presentation Foundation (WPF) .

Bu izlenecek yolda, UserControl bir daire şeklini temsil eden özel bır WPF oluşturacaksınız. Sürükle ve bırak ile veri aktarımını etkinleştirmek için denetime işlevsellik uygulayacaksınız. Örneğin, bir daire denetiminden diğerine sürüklerseniz, Fill Color verileri kaynak çemberden hedefe kopyalanır. Bir daire denetiminden öğesine sürüklerseniz TextBox , Fill renginin dize temsili öğesine kopyalanır TextBox . Ayrıca, TextBox sürükle ve bırak işlevlerini test etmek için iki panel denetimi içeren küçük bir uygulama da oluşturacaksınız. Panellerin bırakılan daire verilerini işlemesini sağlayan bir kod yazacaksınız. Bu, bir panelin alt öğe koleksiyonundan daireler taşımanızı veya kopyalamanızı sağlar.

Bu izlenecek yol aşağıdaki görevleri gösterir:

  • Özel Kullanıcı denetimi oluşturun.

  • Kullanıcı denetimini Sürükle kaynağı olacak şekilde etkinleştirin.

  • Kullanıcı denetiminin bir bırakma hedefi olmasını sağlar.

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

Önkoşullar

Bu yönergeyi tamamlamak için Visual Studio gerekir.

Uygulama projesi oluşturma

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

  1. Visual Basic veya Visual C# ' de adlı yeni bir WPF uygulama projesi oluşturun DragDropExample . Daha fazla bilgi için bkz. Izlenecek yol: Ilk WPF MasaüstüUygulamam.

  2. MainWindow. xaml ' i açın.

  3. Açılış ve kapanış etiketleri arasına aşağıdaki biçimlendirmeyi ekleyin Grid .

    Bu biçimlendirme, test uygulaması için Kullanıcı arabirimi 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 bir kullanıcı denetimi Ekle

Bu bölümde, projeye yeni bir kullanıcı denetimi ekleyeceksiniz.

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

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

    Circle. xaml ve arka plan kodu projeye eklenir.

  3. Circle. xaml açın.

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

  4. GridKullanıcı arabirimi olarak mavi bir daire bulunan basit bir kullanıcı denetimi oluşturmak için aşağıdaki biçimlendirmeyi köke ekleyin.

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

  6. C# dilinde, bir kopya Oluşturucu oluşturmak için parametresiz oluşturucudan sonra aşağıdaki kodu ekleyin. Visual Basic, hem parametresiz bir Oluşturucu hem de kopya Oluşturucu oluşturmak için aşağıdaki kodu ekleyin.

    Kullanıcı denetiminin kopyalanmasına izin vermek için, arka plan kod dosyasına bir kopya Oluşturucu yöntemi eklersiniz. Basitleştirilmiş daire Kullanıcı denetiminde, yalnızca Kullanıcı denetiminin dolgusunu ve 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 ' i açın.

  2. WindowGeçerli uygulamaya BIR XML ad alanı başvurusu oluşturmak için AŞAĞıDAKI xaml 'yi açılış etiketine ekleyin.

    xmlns:local="clr-namespace:DragDropExample"
    
  3. İlk panelde, StackPanel Circle Kullanıcı denetiminin iki örneğini oluşturmak için önce AŞAĞıDAKI xaml 'yi ekleyin.

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

    Panelin tam XAML 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ı denetimindeki Sürükle kaynak olaylarını Uygula

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

Bir sürükleme başlatılırsa (bir fare düğmesine basıldığında ve fare taşındığında), verileri bir içine aktarılacak şekilde paketleyecaksınız DataObject . Bu durumda, Circle denetimi üç veri öğesini paketleyebilir; kendi renk gösterimi ve kendi bir kopyası olan Fill Color dize gösterimi.

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

  1. Açık Circle. xaml. cs veya Circle. xaml. vb.

  2. OnMouseMoveOlay için sınıf işleme sağlamak için aşağıdaki geçersiz kılmayı ekleyin MouseMove .

    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 ettirirken sol fare düğmesine basıldığını denetler.

    • Daire verisini bir olarak paketler DataObject . Bu durumda, daire denetimi üç veri öğesini paketler; kendi renk gösterimi ve kendi bir kopyası olan Fill Color dize gösterimi.

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

      • dragSource – Bu denetime bir başvuru.

      • dataDataObject Önceki kodda oluşturulur.

      • allowedEffects – Veya olan izin verilen sürükle ve bırak işlemleri Copy Move .

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

  4. Daire denetimlerinden birine tıklayın ve panelleri, diğer daireyi ve ' nin üzerine sürükleyin TextBox . Üzerinde sürükleme yaparken TextBox , imleç bir taşımayı belirtecek şekilde değişir.

  5. Bir daireyi üzerine sürüklerken TextBox CTRL tuşuna basın. İmlecin bir kopyayı göstermek için nasıl değiştiği hakkında dikkat edin.

  6. Üzerine bir daire sürükleyip bırakın TextBox . Dairenin dolgusu renginin dize temsili öğesine eklenir TextBox .

    Dairenin dolgusu renginin dize temsili

Varsayılan olarak, imleç bir sürükle ve bırak işlemi sırasında, verilerin hangi etkiyle sonuçlandığını belirten şekilde değişir. GiveFeedbackOlayı işleyerek ve farklı bir imleç ayarlayarak kullanıcıya verilen geri bildirimleri özelleştirebilirsiniz.

Kullanıcıya geri bildirimde bulunun

  1. Açık Circle. xaml. cs veya Circle. xaml. vb.

  2. OnGiveFeedbackOlay için sınıf işleme sağlamak için aşağıdaki geçersiz kılmayı ekleyin GiveFeedback .

    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:

    • EffectsBırakma hedefinin olay işleyicisinde ayarlanan değerleri denetler DragOver .

    • Değere göre özel bir imleç ayarlar Effects . İmlecin, kullanıcıya verilerin ne kadar yürürlükte olacağı hakkında görsel geri bildirim vermesi amaçlanmıştır.

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

  4. Panel, diğer daire ve için daire denetimlerinden birini sürükleyin TextBox . İmleçlerin artık geçersiz kılmada belirttiğiniz özel imleçler olduğuna dikkat edin OnGiveFeedback .

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

  5. Öğesinden metni seçin green TextBox .

  6. greenMetni bir daire denetimine sürükleyin. Sürükle ve bırak işleminin etkilerini belirtmek için varsayılan imleçlerin gösterildiğine dikkat edin. Geri bildirim imleci her zaman Sürükle kaynağı tarafından ayarlanır.

Kullanıcı denetiminde bırakma hedefi olaylarını uygulama

Bu bölümde, Kullanıcı denetiminin bir bırakma hedefi olduğunu, Kullanıcı denetiminin bir bırakma hedefi olmasını sağlayan yöntemleri geçersiz kılacaksınız ve üzerinde bırakılan verileri işleyecek şekilde belirtirsiniz.

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

  1. Circle. xaml açın.

  2. Açma UserControl etiketinde AllowDrop özelliği ekleyin ve olarak ayarlayın 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">
    

OnDropYöntemi, AllowDrop özelliği olarak ayarlandığında true ve sürükleme kaynağındaki veriler daire Kullanıcı denetiminde bırakıldığında çağrılır. Bu yöntemde, bırakılan verileri işleyecek ve verileri daireye uygulamanız gerekecektir.

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

  1. Açık Circle. xaml. cs veya Circle. xaml. vb.

  2. OnDropOlay için sınıf işleme sağlamak için aşağıdaki geçersiz kılmayı ekleyin Drop .

    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:

    • , GetDataPresent Sürüklenen verilerin bir dize nesnesi içerip içermediğinden emin olmak için yöntemini kullanır.

    • , Varsa GetData dize verilerini ayıklamak için yöntemini kullanır.

    • BrushConverterDizeyi öğesine dönüştürmeyi denemek için öğesini kullanır Brush .

    • Dönüştürme başarılı olursa, ' Fill nin, Ellipse daire denetiminin Kullanıcı arabirimini sağlayan öğesine fırça uygular.

    • DropOlayı işlenmiş olarak işaretler. Bu olayı alan diğer öğelerin, Circle Kullanıcı denetiminin bunu ele aldığından emin olmak için bırakma olayını işlenmiş olarak işaretlemelisiniz.

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

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

  5. Metni bir daire denetimine sürükleyin ve bırakın. Daire mavi ile yeşil arasında değişir.

    Bir dizeyi fırçaya Dönüştür

  6. Metni içine yazın green TextBox .

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

  8. Bir daire denetimine sürükleyin ve bırakın. İmlecin, bırakmaya izin verildiğini belirtmek için değiştiği, ancak dairenin rengi geçerli bir renk olmadığından, bu değişikliğin değişmediğine dikkat edin gre .

  9. Yeşil daire denetiminden sürükleyin ve mavi daire denetiminin üzerine bırakın. Daire mavi ile yeşil arasında değişir. Hangi imlecin gösterildiğine dikkat edin, TextBox ya da dairenin Sürükle kaynağı olup olmamasına bağlıdır.

AllowDropÖzelliği true bırakılan verileri olarak ayarlamak ve işlemek bir öğenin bir bırakma hedefi olmasını sağlamak için gereklidir. Ancak, daha iyi bir kullanıcı deneyimi sağlamak için,, ve olaylarını da işlemeniz gerekir DragEnter DragLeave DragOver . Bu olaylarda, denetimler gerçekleştirebilir ve veriler kesilmeden ö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şleip işleyemeyeceğini, sürükleme kaynağını bilgilendirmelidir. Denetim, verilerin nasıl işleyeceğini bilmez ise, bırakmayı reddetmelidir. Bunu yapmak için, DragOver olayı işleyecek ve özelliğini ayarlayacaksınız Effects .

Veri bırakmaya izin verildiğini doğrulamak için

  1. Açık Circle. xaml. cs veya Circle. xaml. vb.

  2. OnDragOverOlay için sınıf işleme sağlamak için aşağıdaki geçersiz kılmayı ekleyin DragOver .

    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 olarak ayarlar None .

    • OnDropCircle Kullanıcı denetiminin sürüklenen verileri işleyemeyeceğini anlamak için yönteminde gerçekleştirilen denetimleri gerçekleştirir.

    • Kullanıcı denetimi verileri işleyebiliyorsanız, Effects özelliğini veya olarak ayarlar Copy Move .

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

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

  5. Metni bir daire denetimine sürükleyin. İmlecin şimdi, geçerli bir renk olmadığından, bırakmaya izin verilmediğini göstermek için değişiklik olduğuna dikkat edin gre .

Bırakma işleminin önizlemesini uygulayarak Kullanıcı deneyimini daha da geliştirebilirsiniz. Circle Kullanıcı denetimi için ve yöntemlerini geçersiz kılacaksınız OnDragEnter OnDragLeave . Veriler denetimin üzerine sürüklendiğinde, geçerli arka plan Fill bir yer tutucu değişkenine kaydedilir. Daha sonra dize bir fırçaya dönüştürülüp Ellipse dairenin Kullanıcı arabirimini sağlayan öğesine uygulanır. Verilerin bırakılmadan dışına sürüklenmesi durumunda özgün Fill değer, daireye yeniden uygulanır.

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

  1. Açık Circle. xaml. cs veya Circle. xaml. vb.

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

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

    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 özelliğini Ellipse _previousFill değişkenine kaydeder.

    • OnDropVerilerin bir öğesine dönüştürülüp dönüştürülmeyeceğini anlamak için yönteminde gerçekleştirilen denetimleri gerçekleştirir Brush .

    • Veriler geçerli bir değerine dönüştürülürse, Brush ' nin öğesine uygular Fill Ellipse .

  4. OnDragLeaveOlay için sınıf işleme sağlamak için aşağıdaki geçersiz kılmayı ekleyin DragLeave .

    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:

    • Değişkenine, Brush _previousFill Fill Ellipse Circle Kullanıcı denetiminin Kullanıcı arabirimini sağlayan öğesine uygular.
  5. Uygulamayı derlemek ve çalıştırmak için F5 tuşuna basın.

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

  7. Metni bırakmadan bir daire denetiminin üzerine sürükleyin. Daire mavi ile yeşil arasında değişir.

    Bir sürükle-ve-bırakma işleminin etkilerini önizleyin

  8. Metni daire denetiminden uzağa sürükleyin. Daire, yeşil ve mavi arasında değişir.

Bir paneli bırakılan verileri alacak şekilde etkinleştirme

Bu bölümde, daire kullanıcı denetimlerini barındıran bölmeleri, sürüklenen daire verileri için bırakma hedefleri olarak davranacak şekilde etkinleştirirsiniz. Bir daireyi bir panelden diğerine taşımanızı veya bir daireyi Sürükleyip bırakırken CTRL tuşunu basılı tutarak bir daire denetiminin kopyasını yapmanızı sağlayan kodu uygulayacaksınız.

  1. MainWindow. xaml ' i açın.

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

    <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 dosyasını açın.

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

    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, DataObject Circle Kullanıcı denetimiyle paketlenmiş ve çağrısına geçilen "nesne" verilerini içerip içermediğini denetler DoDragDrop .

    • "Nesne" verileri mevcutsa, CTRL tuşuna basıldığını denetler.

    • CTRL tuşuna basıldığında Effects özelliğini olarak ayarlar Copy . Aksi takdirde, Effects özelliğini olarak ayarlayın Move .

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

    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:

    • DropEtkinliğin zaten işlenmiş olup olmadığını denetler. Örneğin, bir daire olayı işleyen başka bir daire üzerinde bırakıldığında Drop , daireyi içeren panelin da işlenmesi için bu işleci istemezsiniz.

    • DropOlay işlenmezse, CTRL tuşuna basıldığını denetler.

    • Oluştuğunda CTRL tuşuna basıldığında Drop , daire denetiminin bir kopyasını oluşturur ve Children koleksiyonuna ekler StackPanel .

    • CTRL tuşuna basılsa, daireyi Children üst bölmesinin koleksiyonundan, Children üzerinde bırakılan panelin koleksiyonuna taşımış olur.

    • Yöntemi, Effects DoDragDrop bir taşıma veya kopyalama işleminin gerçekleştirilip gerçekleştirilmediğini bildirmek için özelliği ayarlar.

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

  7. Öğesinden metni seçin green TextBox .

  8. Metni bir daire denetiminin üzerine sürükleyin ve bırakın.

  9. Sol panelden bir daire denetimini sağ panele sürükleyin ve bırakın. Daire, Children sol bölmenin koleksiyonundan kaldırılır ve sağ bölmenin alt öğe koleksiyonuna eklenir.

  10. Bir daire denetimini, içindeki panelden diğer panele sürükleyin ve CTRL tuşuna basarak bırakın. Daire kopyalanır ve kopya, Children alan paneli koleksiyonuna eklenir.

    CTRL tuşuna basıldığında bir daireyi sürükleme

Ayrıca bkz.