I have read various solutions to the problem and I now wonder which one is to be preferred in which situation (and mine especially)
I have created a Custom Control that Renders a Color wheel and a circle ( Ellipse
) on a canvas in the middle. I now want to be able to click and drag that circle as a selector on the color wheel.
Possible solutions include: Overriding the OnClick
and / or OnMouseMove
events and update the circles position by either dependency properties or using TemplateParts or even generating the circle in the Controls Code Behind.
I wonder if it would also be possible to use triggers in XAML to achieve this effect and which solution would deliver the "smoothest" motion.
Update 1: To address comments, here is some code:
ColorPicker.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TrigDebugUtil.Controls">
<Style x:Key="ColorPicker" TargetType="{x:Type local:ColorPicker}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ColorPicker}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Image Source="{TemplateBinding ColorWheelImage}" Width="500" Height="500"/>
<Canvas Width="10" Height="10" HorizontalAlignment="Center" VerticalAlignment="Center">
<Ellipse Fill="{TemplateBinding Property=SelectedColor}" Width="10" Height="10" Stroke="Black" StrokeThickness=".5" />
</Canvas>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
ColorPicker.cs
namespace TrigDebugUtil.Controls
{
public class ColorPicker : Control
{
#region Private Fields
#endregion //Private Fields
#region Dependency Properties
public static readonly DependencyProperty ColorWheelImageProperty = DependencyProperty.Register("ColorWheelImage", typeof(WriteableBitmap), typeof(ColorPicker));
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(SolidColorBrush), typeof(ColorPicker));
#endregion //Dependency Properties
#region Properties
public WriteableBitmap ColorWheelImage
{
get { return (WriteableBitmap)GetValue(ColorWheelImageProperty); }
private set { SetValue(ColorWheelImageProperty, value); }
}
public SolidColorBrush SelectedColor
{
get { return (SolidColorBrush)GetValue(SelectedColorProperty); }
private set { SetValue(SelectedColorProperty, value); }
}
#endregion //Properties
static ColorPicker()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker)));
}
public ColorPicker()
{
ColorWheelImage = new WriteableBitmap(500, 500, 96, 96, PixelFormats.Rgb24, null);
SelectedColor = Brushes.White;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Byte[] pixels = new Byte[1500 * 500];
// Update algo here
ColorWheelImage.WritePixels(new Int32Rect(0, 0, 500, 500), pixels, 1500, 0);
}
}
}
I want to be able to click on the ellipse in the canvas and move it to another location in the control itself (ie on the image)
For people having the same issue, one possible solution is to implement the draggable object as a Thumb
and overriding its DragStarted
DragDelta
and DragCompleted
events.
Here's an example:
private void OnThumbDragDelta(object sender, DragDeltaEventArgs e)
{
Thumb thumb = sender as Thumb;
double newX = Canvas.GetLeft(thumb) + e.HorizontalChange;
double newY = Canvas.GetTop(thumb) + e.VerticalChange;
Canvas.SetLeft(thumb, newX);
Canvas.SetTop(thumb, newY);
// This is optional for routed events.
e.RoutedEvent = ThumbDragDeltaEvent;
RaiseEvent(e);
}
without using the DragStarted
and DragCompleted
Events.
I'd like to see comments on wether this is a preferred solution or if it has any disadvantages. From what I can see it's not the most efficient, on fast mouse movements, the thumb movement is delayed and not always "right under the mouse"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.