有人可以帮我解决我的问题 . 我正在创建一个可以在Image上绘制矩形的程序 . 我正在使用WPF和MVVM模式 .
要求是 . 观看者可以缩放和平移图像 . 使用调整大小绘制矩形并移动绘制的矩形 .
然后我从下面的链接中找到了这个答案
我从答案中实现了ZoomBorder类 .
然后因为我还需要绘制矩形 . 我修改了代码并添加了返回Rect的Dependency Property
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));
这就是我使用它的方式
<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>
然后我有一个工作平移缩放和绘图 . 但是我仍然需要调整大小并移动绘制的矩形 .
然后经过几个小时的搜索,我发现这个博客调整大小并在画布中移动对象
http://www.voidcn.com/article/p-krlsqrhc-uw.html
但我的问题是 . 我无法在画布中选择绘制的矩形 .
以下是在画布中选择控件的代码
// 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? 问题是所选的控件是 Grid
而不是 Canvas
- 我该如何解决这个问题?
如果我打算删除 Grid
. 我会有一个错误"the property Child is set more than once" . 我需要画布和图像 . 我找不到解决方案所以我决定在这里问一下 .
1 回答
标记的工作方式是将一组视图模型(或任何它们)作为RectItems呈现给itemscontrol .
每个都被模板化为一个矩形 .
如果你想删除一个,那么把它的viewmodel取出RectItems . 假设它是一个可观察的集合,那么它将通知集合发生变化,矩形将被删除 .
当你这样做时,特定的RectItem将是selectedElement的datacontext:
所以 grab 它的datacontext并将其转换为RectItem .
然后获取对RectItems所在的viewmodel的引用 . 也许那是窗口的datacontext . 然后,您可以在RectItems上使用.Remove()将其取出 .