Перетащите на Drop на составной пользовательский элемент управления с несколькими текстовыми полями - PullRequest
3 голосов
/ 19 января 2011

У меня есть пользовательский элемент управления, который содержит два текстовых поля, а также некоторые другие элементы управления.Я хочу иметь возможность перетаскивать сложный тип на этот элемент управления, и я хочу, чтобы весь элемент управления был целью удаления, включая текстовые поля и пространство вокруг составных элементов управления.Когда данные отбрасываются, они разделяются на поля компонентов, каждое из которых представлено элементами управления в пользовательском элементе управления.

Проблема, с которой я сталкиваюсь, заключается в том, что текстовые поля (если я установил AllowDrop в значение true) пытаютсясделать свою собственную вещь перетаскивания, и будет индивидуально принимать только текстовый формат данных перетаскивания.Если для текстовых полей установить значение AllowDrop, равное false, удаление будет отключено для текстовых полей.Я могу перетащить свои сложные данные в метки, флажки и т. Д., И они будут вести себя точно так, как я ожидал.

Кроме того, пространство вокруг других элементов управления, похоже, не считается допустимой целью перетаскивания.

Любые идеи о том, как заставить текстовые поля вести себя как элементы управления (такие как метки, флажкиили комбинированный список), и почему сетка не считается допустимой целью удаления?

Источник для пользовательского элемента управления:

<UserControl x:Class="DragDropTester.CompositeControl"
         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="226" d:DesignWidth="428" AllowDrop="True">
    <Grid AllowDrop="True">        
        <TextBox Height="23" Margin="115,12,12,0" Name="textBox1" VerticalAlignment="Top" AllowDrop="False" />
        <Label Content="TextBox 1:" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" Name="label1" VerticalAlignment="Top" Width="97" />
        <TextBox Height="23" Margin="115,41,12,0" Name="textBox2" VerticalAlignment="Top" AllowDrop="False" />
        <Label Content="TextBox 2:" Height="28" HorizontalAlignment="Left" Margin="12,41,0,0" Name="label2" VerticalAlignment="Top" Width="97" />
        <CheckBox Content="CheckBox" Height="16" Margin="115,70,150,0" Name="checkBox1" VerticalAlignment="Top" />
        <ComboBox Height="23" Margin="115,92,12,0" Name="comboBox1" VerticalAlignment="Top" />
    </Grid>
</UserControl>

и код позади:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DragDropTester {
    /// <summary>
    /// Interaction logic for CompositeControl.xaml
    /// </summary>
    public partial class CompositeControl : UserControl {

        public CompositeControl() {
            InitializeComponent();

            PreviewDragEnter += new DragEventHandler(CompositeControl_DragEnter);
            this.PreviewDragOver += new DragEventHandler(CompositeControl_DragEnter);

            Drop += new DragEventHandler(CompositeControl_Drop);
        }

        void CompositeControl_Drop(object sender, DragEventArgs e) {
            var complex = e.Data.GetData("ComplexDragData") as ComplexDragData;
            if (complex != null) {
                this.textBox1.Text = complex.Text1;
                this.textBox2.Text = complex.Text2;
                this.checkBox1.IsChecked = complex.BoolValue;
            }
        }

        void CompositeControl_DragEnter(object sender, DragEventArgs e) {
            var complex = e.Data.GetData("ComplexDragData") as ComplexDragData;
            if (complex != null) {
                e.Effects = DragDropEffects.Link;
            } else {
                e.Effects = DragDropEffects.None;
            }

            e.Handled = true;
        }
    }
}

И для главного окна, в котором размещены пользовательский элемент управления и источник перетаскивания ...

XAML:

<Window x:Class="DragDropTester.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:src="clr-namespace:DragDropTester"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="40" />
        </Grid.RowDefinitions>
        <src:CompositeControl />
        <Label Content="Drag Source" Grid.Row="1" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Margin="5" Background="LightGray" Name="lblDragSource" />
    </Grid>
</Window>

C # код позади:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DragDropTester {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {

        private Point _startPoint;
        private bool _IsDragging;

        public MainWindow() {
            InitializeComponent();

            lblDragSource.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(lblDragSource_PreviewMouseLeftButtonDown);
            lblDragSource.PreviewMouseMove += new MouseEventHandler(lblDragSource_PreviewMouseMove);
        }

        void lblDragSource_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
            _startPoint = e.GetPosition(sender as IInputElement);
        }

        void lblDragSource_PreviewMouseMove(object sender, MouseEventArgs e) {

            if (_startPoint == null) {
                return;
            }

            if (e.LeftButton == MouseButtonState.Pressed && !_IsDragging) {
                Point position = e.GetPosition(sender as IInputElement);
                if (Math.Abs(position.X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(position.Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance) {
                    StartDrag(sender as DependencyObject);
                }
            }            
        }

        private void StartDrag(DependencyObject dragSource) {
            var data = new DataObject();
            var dragData = new ComplexDragData { Text1 = "This is text1", Text2 = "This is text2", BoolValue = true };
            data.SetData("ComplexDragData", dragData);
            data.SetData(DataFormats.Text, dragData.ToString());

            try {
                _IsDragging = true;
                DragDrop.DoDragDrop(dragSource, data, DragDropEffects.Copy | DragDropEffects.Link);
            } finally {
                _IsDragging = false;
            }

        }
    }

    public class ComplexDragData {
        public String Text1 { get; set; }
        public String Text2 { get; set; }
        public bool BoolValue { get; set; }

        public override string ToString() {
            return string.Format("text1: {0} text2: {1} Bool: {2}", Text1, Text2, BoolValue );
        }
    }
}

1 Ответ

4 голосов
/ 19 января 2011

Похоже, что я могу получить желаемое поведение, перехватывая события перетаскивания текстовых полей по отдельности:

    public CompositeControl() {
        InitializeComponent();

        PreviewDragEnter += new DragEventHandler(CompositeControl_DragEnter);
        PreviewDragOver += new DragEventHandler(CompositeControl_DragEnter);

        textBox1.PreviewDragEnter += new DragEventHandler(textBox_PreviewDragEnter);
        textBox1.PreviewDragOver += new DragEventHandler(textBox_PreviewDragEnter);
        textBox1.PreviewDrop += new DragEventHandler(CompositeControl_Drop);

        textBox2.PreviewDragEnter += new DragEventHandler(textBox_PreviewDragEnter);
        textBox2.PreviewDragOver += new DragEventHandler(textBox_PreviewDragEnter);
        textBox2.PreviewDrop += new DragEventHandler(CompositeControl_Drop);

        Drop += new DragEventHandler(CompositeControl_Drop);
    }

    void textBox_PreviewDragEnter(object sender, DragEventArgs e) {
        e.Handled = true;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...