Невозможно взаимодействовать с предметами на слое украшения

введите описание изображения здесь

На изображении выше показан пример меню параметров в MS Word 2010, когда вы щелкаете текстовое поле в документе. Я пытаюсь реализовать что-то подобное, используя украшения в WPF, и в настоящее время борюсь с реализацией.

Я создал 2 украшения, которые называются optionsButtonAdorner и AdvancedOptionsAdorner. Когда я нажимаю на свой элемент на холсте, я показываю optionsButtonAdorner с небольшой скользящей анимацией, а когда я нажимаю на optionsButtonAdorner, я показываю AdvancedOptionsAdorner с той же скользящей анимацией. Я получил указанную выше задачу, работающую правильно, и моя система правильно отображает оба украшения, как показано на рисунке выше.

Но сложная часть состоит в том, что если я попытаюсь поместить что-нибудь в AdvancedOptionsAdorner, я могу отключить кнопку внутри рекламного средства, но я не получаю HitTest на кнопке (то же самое с любым другим элементом управления, например, если я попытаюсь поставить тестовое поле, которое я не могу получить сосредоточиться на нем или взаимодействовать с ним). Если я использую snoop для просмотра объектов, я вижу, что кнопка и текстовое поле включены, а для Hittest установлено значение true. Но если заглянуть немного дальше, я на самом деле получаю события mousedown на холсте Iteself, а не объекты украшения. Теперь я думаю, ошибочен ли сам мой подход. Ниже приведен пример кода AdvancedOptionsAdorner.

Спасибо за любую помощь и извините за такой длинный пост.

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>

Ниже представлен рендер, который я получаю после реализации украшений.

введите описание изображения здесь

Редактировать -

Мне удалось заставить его работать, вот рендер, который я получаю введите описание изображения здесь

Я ошибался, переопределяя методы GetVisualChild и VisualChildrenCount. Вместо этого я создал свойство VisualCollection в классе adorner и добавил свой contentPresenter в эту коллекцию, а переопределения просто вернули ожидаемые результаты, такие как visualCollection [i] для VisualChild и visualCollection.Count для VisualChildrenCount.

Кроме того, у меня не было проблем с интерактивностью пользовательского интерфейса, потому что я передаю dataContext моего элемента в украшение, а также большинство команд, которые входят в украшение AdvancedOptions, являются командами Prism Composite, и они запускаются в соответствующих моделях просмотра


person Krishna    schedule 14.04.2014    source источник


Ответы (1)


Впечатляющий код проекта - мои комплименты! К сожалению, я думаю, что Adorner - хотя и весьма полезен для множества целей «украшения», здесь служить не будет. Вам потребуется полная интерактивность с этим элементом управления, который Adorner не предназначен для предоставления. Здесь вам нужны обычные элементы UX. Украшения реализованы как своего рода отдельный слой от остальной части дерева UIElement. Я сам шел по этому пути, прежде чем осознал это. Кстати, мне бы хотелось узнать больше о вашем проекте и о том, насколько успешно вы его реализуете с помощью WPF. Ударь меня, если я могу чем-нибудь помочь. И наилучшие пожелания.

person JamesWHurst    schedule 16.04.2014
comment
Спасибо за интерес к этому. Мне удалось исправить проблему, и я объяснил ее в моем редактировании исходного сообщения. У меня не было проблем с интерактивностью, так как я использую составные команды в этом украшении. На данный момент я помещаю в него только команды копирования и вставки, но теперь, когда код работает, мы можем поместить все, что захотим, например, выравнивание, шрифты и т. Д. - person Krishna; 16.04.2014