The improved circle usercontrol has a CircleID property
Circle.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace WpfApp3
{
/// <summary>
/// Interaction logic for Circle.xaml
/// </summary>
public partial class Circle : UserControl
{
private Brush _previousFill = null;
public Circle()
{
InitializeComponent();
}
public Circle(Circle c)
{
InitializeComponent();
this.circleUI.Height = c.circleUI.Height;
this.circleUI.Width = c.circleUI.Height;
this.circleUI.Fill = c.circleUI.Fill;
this.CircleID = c.CircleID;
}
public int CircleID
{
get { return (int)GetValue(CircleIDProperty); }
set { SetValue(CircleIDProperty, value); }
}
public static readonly DependencyProperty CircleIDProperty =
DependencyProperty.Register("CircleID", typeof(int), typeof(Circle));
protected override void OnDragEnter(DragEventArgs e)
{
base.OnDragEnter(e);
_previousFill = circleUI.Fill;
if (e.Data.GetDataPresent(DataFormats.StringFormat))
{
string dataString = (string)e.Data.GetData(DataFormats.StringFormat);
BrushConverter converter = new BrushConverter();
if (converter.IsValid(dataString))
{
Brush newFill = (Brush)converter.ConvertFromString(dataString.ToString());
circleUI.Fill = newFill;
}
}
}
protected override void OnDragLeave(DragEventArgs e)
{
base.OnDragLeave(e);
circleUI.Fill = _previousFill;
}
protected override void OnDrop(DragEventArgs e)
{
base.OnDrop(e);
if (e.Data.GetDataPresent(DataFormats.StringFormat))
{
string dataString = (string)e.Data.GetData(DataFormats.StringFormat);
BrushConverter converter = new BrushConverter();
if (converter.IsValid(dataString))
{
Brush newFill = (Brush)converter.ConvertFromString(dataString);
circleUI.Fill = newFill;
if (e.KeyStates.HasFlag(DragDropKeyStates.ControlKey))
{
e.Effects = DragDropEffects.Copy;
}
else
{
e.Effects = DragDropEffects.Move;
}
}
}
e.Handled = true;
}
protected override void OnDragOver(DragEventArgs e)
{
base.OnDragOver(e);
e.Effects = DragDropEffects.None;
if (e.Data.GetDataPresent(DataFormats.StringFormat))
{
string dataString = (string)e.Data.GetData(DataFormats.StringFormat);
BrushConverter converter = new BrushConverter();
if (converter.IsValid(dataString))
{
if (e.KeyStates.HasFlag(DragDropKeyStates.ControlKey ))
{
e.Effects = DragDropEffects.Copy;
}
else
{
e.Effects = DragDropEffects.Move;
}
}
}
e.Handled = true;
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.LeftButton == MouseButtonState.Pressed)
{
DataObject data = new DataObject();
data.SetData(DataFormats.StringFormat, circleUI.Fill.ToString());
data.SetData("Double", circleUI.Height);
data.SetData("Object", this);
data.SetData("CircleID", CircleID);
DragDrop.DoDragDrop(this, data, DragDropEffects.Copy | DragDropEffects.Move);
}
}
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;
}
}
}
Circle.xaml
<UserControl x:Class="WpfApp3.Circle" x:Name="CircleControl"
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"
xmlns:local="clr-namespace:WpfApp3"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
AllowDrop="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Content="{Binding Path=CircleID, ElementName=CircleControl}" Grid.Row="0" />
<Ellipse x:Name="circleUI" Grid.Row="1"
Height="100" Width="100"
Fill="Blue" />
</Grid>
</UserControl>
This version of MainWindow identify the circle usercontrol by CircleID and parent panel by its Name
MainWindow.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WpfApp3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void panel_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("Object"))
{
if (e.KeyStates == DragDropKeyStates.ControlKey )
{
e.Effects = DragDropEffects.Copy;
}
else
{
e.Effects = DragDropEffects.Move;
}
}
}
private void panel_Drop(object sender, DragEventArgs e)
{
string panelName;
if (e.Handled == false)
{
Panel _panel = (Panel)sender;
UIElement _element = (UIElement)e.Data.GetData("Object");
if (_panel!= null && _element!=null)
{
panelName = _panel.Name;
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);
int cid = _circle.CircleID;
string s = cid.ToString() + " is in " + panelName;
MessageBox.Show(s);
_panel.Children.Add(_circle);
e.Effects = DragDropEffects.Copy;
}
else if (e.AllowedEffects.HasFlag(DragDropEffects.Move))
{
Circle _circle = new Circle((Circle)_element);
int cid = _circle.CircleID;
string s = cid.ToString() + " is in " + panelName;
MessageBox.Show(s);
_parent.Children.Remove(_element);
_panel.Children.Add(_element);
e.Effects = DragDropEffects.Move;
}
}
}
}
}
}
}
MainWindow.xaml
<Window x:Class="WpfApp3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp3"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
x:Name="LeftPanel"
Background="Beige"
AllowDrop="True"
DragOver="panel_DragOver"
Drop="panel_Drop"
>
<TextBox Width="Auto" Margin="2"
Text="green"/>
<local:Circle Margin="2" CircleID="1" />
<local:Circle Margin="2" CircleID="2"/>
</StackPanel>
<StackPanel Grid.Column="1"
x:Name="RightPanel"
Background="Bisque"
AllowDrop="True"
DragOver="panel_DragOver"
Drop="panel_Drop"
>
</StackPanel>
</Grid>
</Window>