无法与装饰层上的项目交互

5

在文档中单击文本框后,在 MS Word 2010 中出现的选项菜单示例。 我想使用 WPF 中的 adorners 实现类似的功能,并且目前在实现方面遇到了困难。</p>

<p>我创建了两个 adorner,名为 optionsButtonAdorner 和 AdvancedOptionsAdorner。 当我单击画布上的项目时,我会显示 optionsButtonAdorner 并带有一个小的滑动动画,当我单击 optionsButtonAdorner 时,我会使用相同的滑动动画显示 AdvancedOptionsAdorner。 我已经成功地完成了以上任务,并且我的系统正确地呈现了这两个 adorner,就像上面的图片一样。</p>

<p>但是复杂的部分是,如果我尝试将任何内容放入 AdvancedOptionsAdorner 中,我可以在 adorner 中显示一个按钮,但是我无法在该按钮上获得任何 HitTest(同样适用于任何其他控件,例如如果我尝试放置 testbox,我无法使其获得焦点或与其交互)。 如果我使用 snoop 查看对象,则可以看到按钮和文本框已启用,并且 hittest 设置为 true。 但是更深入地查看后,我实际上在画布 Iteself 上获取 mousedown 事件,而不是 adorner 对象。 现在我在考虑我的方法是否错误。下面是 AdvancedOptionsAdorner 的示例代码。</p>

<p>感谢任何帮助和对如此冗长的帖子表示抱歉。</p>

<pre class=public DesignerItemAdvancedOptionsAdorner(DesignerControl designerItem):base(designerItem) { _designerItem = designerItem; DataTemplate dataTemplate = (DataTemplate)FindResource("DesignerItemAdvancedOptionsAdorner"); _contentPresenter = new ContentPresenter() { ContentTemplate = dataTemplate, Opacity = 0.75 }; Loaded += DesignerItemAdvancedOptionsAdorner_Loaded; Unloaded += DesignerItemAdvancedOptionsAdorner_Unloaded; } private void DesignerItemAdvancedOptionsAdorner_Loaded(object sender, RoutedEventArgs e) { double newDistance = Math.Round((_designerItem.ControlActualWidth * ActiveZoomLevel) + 50); AnimateMargin(new Thickness((_designerItem.ControlActualWidth * ActiveZoomLevel) + 45, 0, 0, 0), new Thickness(newDistance, 0, 0, 0), 0.1); } protected override Visual GetVisualChild(int index) { return _contentPresenter; } protected override int VisualChildrenCount { get { return 1; } }

以下是装饰器的数据模板。
<DataTemplate x:Key="DesignerItemAdvancedOptionsAdorner">
        <Grid RenderTransformOrigin="0.5,0.5" Margin="0,-10,0,0" Height="320" Width="160" HorizontalAlignment="Left">
            <Path Stroke="{DynamicResource ApplicationPrimaryColour}" StrokeThickness="1" Fill="White">
                <Path.Data>
                    <CombinedGeometry GeometryCombineMode="Union">
                        <CombinedGeometry.Geometry1>
                            <RectangleGeometry  Rect="0,0,140,280">
                                <RectangleGeometry.Transform>
                                    <TranslateTransform X="10" />
                                </RectangleGeometry.Transform>
                            </RectangleGeometry>
                        </CombinedGeometry.Geometry1>
                        <CombinedGeometry.Geometry2>
                            <PathGeometry>
                                <PathFigure StartPoint="0,20">
                                    <LineSegment Point="10,10" />
                                    <LineSegment Point="10,30" />
                                </PathFigure>
                            </PathGeometry>
                        </CombinedGeometry.Geometry2>
                    </CombinedGeometry>
                </Path.Data>
              </Path>
            <TextBlock Text="Options" HorizontalAlignment="Center" VerticalAlignment="Top" FontWeight="Bold" Margin="0,5,0,0"/>
            <Button HorizontalAlignment="Center" VerticalAlignment="Center" Height="40" Width="100" Content="Test"/>
        </Grid>
    </DataTemplate>

下面是我实现装饰器后得到的渲染结果。 enter image description here 编辑-
我设法使其工作,下面是我得到的渲染结果 enter image description here 我错误地覆盖了 GetVisualChild 和 VisualChildrenCount 方法。相反,我在装饰器类中创建了一个 VisualCollection 属性,并将我的 contentPresenter 添加到该集合中,然后重写返回预期结果的方法,如 visualCollection[i] 用于 VisualChild,visualCollection.Count 用于 VisualChildrenCount。
此外,我没有任何与 UI 交互的问题,因为我将我的项的数据上下文传递给了装饰器,而且大多数进入 AdvancedOptions 装饰器的命令都是 Prism 组合命令,并且会在相关的 ViewModel 中触发。
1个回答

0

这是一些令人印象深刻的项目代码 - 我的祝贺!不幸的是,我认为 Adorner - 虽然对于许多“装饰”目的非常有用,但在这里不会起作用。您需要与此控件进行完全交互,而 Adorner 并不打算提供此功能。在这里,您需要常规的 UX 元素。装饰是作为 UIElement 树的一种独立层实现的。我之前也曾走过这条路,后来才意识到这一点。顺便说一下,如果我能提供任何帮助,请联系我,我很想了解更多关于您的项目以及您在使用 WPF 实现它方面的成功情况。最好的祝愿。


感谢您对此的关注。我成功修复了问题,并在原始帖子的编辑中解释了该问题。我在那个装饰器中使用了复合命令,因此互动性方面没有任何问题。目前,我只在其中放置了复制和粘贴命令,但现在代码已经可以正常工作,我们可以放置任何想要的东西,如对齐、字体等。 - Krishna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接