Can someone please help me with my problem. I am creating a program that can draw a rectangle on an Image. I am using WPF and MVVM Pattern.
The requirement is. The viewer can zoom and pan the image. Draw rectangle with resize and move the drawn rectangle.
Then I found this answer from the link below
I implemented the ZoomBorder class from the answer.
Then because I also need to draw rectangle. I modified the code and added Dependency Property that returns Rect
public Rect Rect
{
get { return (Rect)GetValue(RectProperty); }
set { SetValue(RectProperty, value); }
}
// Using a DependencyProperty as the backing store for Rect. This enables animation, styling, binding, etc...
public static readonly DependencyProperty RectProperty =
DependencyProperty.Register("Rect", typeof(Rect), typeof(ZoomBorder),
new FrameworkPropertyMetadata(new Rect(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, null));
And this is how i use it
<Viewer:ZoomBorder x:Name="img" Rect="{Binding Rect}" IsDraw="{Binding IsDraw}">
<Grid>
<Image Height="{Binding ActualHeight, ElementName=img, UpdateSourceTrigger=PropertyChanged}" Width="{Binding ActualWidth, ElementName=img, UpdateSourceTrigger=PropertyChanged}" Stretch="None" Source="img_05_l.jpg"/>
<ItemsControl ItemsSource="{Binding RectItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="canvas" Background="Transparent" Height="{Binding ActualHeight, ElementName=img, UpdateSourceTrigger=PropertyChanged}" Width="{Binding ActualWidth, ElementName=img, UpdateSourceTrigger=PropertyChanged}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.Left" Value="{Binding X, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Setter Property="Canvas.Top" Value="{Binding Y, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="{Binding Width}"
Height="{Binding Height}"
Fill="Transparent"
Stroke="Blue"
StrokeThickness="1" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Viewer:ZoomBorder>
Then I have a working pan zoom and drawing. But I still need the resize and move the drawn rectangle.
Then after hours of searching I found this blog which resize and move the objects in the canvas
http://www.voidcn.com/article/p-krlsqrhc-uw.html
but my problem is. I can't select the drawn rectangle in canvas.
Here is the code for selecting the control in the canvas
// Handler for element selection on the canvas providing resizing adorner
void myCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Remove selection on clicking anywhere the window
if (selected)
{
selected = false;
if (selectedElement != null)
{
// Remove the adorner from the selected element
aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]);
selectedElement = null;
}
}
// If any element except canvas is clicked,
// assign the selected element and add the adorner
if (e.Source != myCanvas)
{
_isDown = true;
_startPoint = e.GetPosition(myCanvas);
selectedElement = e.Source as UIElement;
_originalLeft = Canvas.GetLeft(selectedElement);
_originalTop = Canvas.GetTop(selectedElement);
aLayer = AdornerLayer.GetAdornerLayer(selectedElement);
aLayer.Add(new ResizingAdorner(selectedElement));
selected = true;
e.Handled = true;
}
}
But my problem is how can I select the drawn rectangle? The problem is the control selected is the Grid
not the Canvas
- how can I solve this problem?
If I'm going to remove the Grid
. I will have an error "the property Child is set more than once". I need both of the canvas and the image. I can't find a solution so I decided to ask here.