На изображении выше показан пример меню параметров в 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, и они запускаются в соответствующих моделях просмотра