如何在网格中选择一个孩子?

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 绑定到父行

使用 jQuery 如何在使用 .closest() 时选择一个孩子?

如何在CSS中选择具有特定类名的“最后一个孩子”?

如何仅取消选择网格中的某些行?

如何在 extjs 3 网格中选择行以及如何放置过滤器