如何在网格中选择一个孩子?
Posted
技术标签:
【中文标题】如何在网格中选择一个孩子?【英文标题】:How to select a child in a grid? 【发布时间】:2018-12-10 11:29:48 【问题描述】:谁能帮我解决我的问题。我正在创建一个可以在图像上绘制矩形的程序。我正在使用 WPF 和 MVVM 模式。
要求是。查看者可以缩放和平移图像。通过调整大小绘制矩形并移动绘制的矩形。
然后我从下面的链接中找到了这个答案
Pan & Zoom Image
我从答案中实现了 ZoomBorder 类。
然后因为我还需要画矩形。我修改了代码并添加了返回 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));
这就是我使用它的方式
<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;
但我的问题是如何选择绘制的矩形?问题是选择的控件是Grid
而不是Canvas
- 我该如何解决这个问题?
如果我要删除Grid
。我会有一个错误“属性 Child 被设置了不止一次”。我需要画布和图像。我找不到解决方案,所以我决定在这里问。
【问题讨论】:
【参考方案1】:标记的工作方式是您将一组视图模型(或任何它们)作为 RectItems 呈现给 itemscontrol。
每一个都被模板化成一个矩形。
如果你想删除一个然后把它的视图模型从 RectItems 中取出。假设它是一个 observablecollection,那么它会通知集合已更改并且矩形将被移除。
当你这样做时,特定的 RectItem 将是 selectedElement 的数据上下文:
selectedElement = e.Source as UIElement;
所以抓住它的 datacontext 并将其转换为 RectItem 是什么。
然后获取对 RectItems 所在的视图模型的引用。也许这就是窗口的数据上下文。 然后,您可以在 RectItems 上使用 .Remove() 将其取出。
【讨论】:
以上是关于如何在网格中选择一个孩子?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 c# 中使用统一组合网格并获取相对于主父级的点击位置
WPF 网格与孩子。如何将子 IsEnabled 绑定到父行