2011-01-19 46 views
3

我有一個包含兩個文本框以及一些其他控件的用戶控件。我希望能夠將複雜類型拖放到此控件上,並且我希望整個控件成爲放置目標,包括合成控件周圍的文本框和空間。當數據被刪除時,它被拆分成組件字段,每個組件字段都由用戶控件中的控件表示。將Drop拖放到具有多個文本框的複合用戶控件上

我遇到的問題是,文本框(如果我將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); 
     } 
    } 
} 
+0

編輯:看來,如果我設置的背景網格的顏色變成某種東西,它將允許它作爲放置目標(例如, Background =「{x:Static SystemColors.WindowBrush}」) – David 2011-01-19 05:06:55

回答

4

它看起來像我能得到我想要通過掛鉤拖行爲/放單獨的文本框的事件:

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