Цель состоит в том, чтобы создать словарь ресурсов с геометрией путей к значкам для моего настраиваемого шаблона кнопки.
Что пока работает:
ResourceDictionary:
<Geometry x:Key = "ArrowDown">
M0,10 M10,0 M5,1 L5,7 4.2,7 5,8 5.8,7 5,7
</Geometry>
<Geometry x:Key = "ArrowUp">
M0,0 M10,10 M5,9 L5,3 4.2,3 5,2 5.8,3 5,3
</Geometry>
Прикрепленное свойство для Пути:
public static Geometry GetIconPath(UIElement element)
{
return (Geometry)element.GetValue(IconPathProperty);
}
public static void SetIconPath(UIElement element, Geometry value)
{
element.SetValue(PIconPathProperty, value);
}
public static readonly DependencyProperty IconPathProperty =
DependencyProperty.RegisterAttached("IconPath", typeof(Geometry), typeof(Attached));
Шаблон:
<ControlTemplate x:Key = "ButtonTemplate" TargetType = "{x:Type Button}">
<Viewbox>
<Path Name = "Icon" Stroke = "Black" StrokeThickness = "1" Stretch = "Uniform"
Data = "{Binding (local:Attached.IconPath), RelativeSource = {RelativeSource TemplatedParent}}"/>
</Viewbox>
<ControlTemplate.Triggers>
<Trigger Property = "IsEnabled" Value = "False">
<Setter Property = "Stroke" TargetName = "Icon" Value = "Gray"/>
<Setter TargetName = "Icon" Property = "Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth = "0.2" Color = "Black" Direction = "125"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Кнопка:
<Button local:Attached.IconPath = "{StaticResource ArrowDown}"/>
Это работает нормально, но теперь у меня есть дополнительный уровень сложности: некоторые значки нужно заливать, а другие - нет. И я хотел бы, чтобы эта информация была в ResourceDictionary с помощью GeometryData.
Одним из решений было бы сохранить весь Path в ResourceDictionary, но, как вы можете видеть в ControlTemplate, мне нужно иметь доступ к Path для запуска DropShadowEffect.
Итак, альтернативное решение, которое я пытаюсь использовать, - использовать POCO для хранения обоих элементов в:
public class IconData
{
public bool Fill { get; set; }
public Geometry Geometry { get; set; }
}
Итак, ResourceDictionary теперь содержит:
<local:IconData x:Key = "ArrowUp" Fill = "True" Geometry = "
M0,0 M10,10 M5,9 L5,3 4.2,3 5,2 5.8,3 5,3"/>
С соответствующим присоединенным свойством ControlTemplate становится:
<ControlTemplate x:Key = "ButtonTemplate" TargetType = "{x:Type Button}">
<Viewbox>
<Path Name = "Icon" Stroke = "Black" StrokeThickness = "1" Stretch = "Uniform"
Data = "{Binding (local:Attached.IconData.Geometry), RelativeSource = {RelativeSource TemplatedParent}}"/>
</Viewbox>
<ControlTemplate.Triggers>
<Trigger Property = "local:Attached.IconData.Fill" Value = "True">
<Setter Property = "Fill" TargetName = "Icon" Value = "#00000000"/>
</Trigger>
<Trigger Property = "IsEnabled" Value = "False">
<Setter Property = "Stroke" TargetName = "Icon" Value = "Gray"/>
<Setter TargetName = "Icon" Property = "Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth = "0.2" Color = "Black" Direction = "125"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
И, к сожалению, обе ссылки на IconData здесь говорят о Nested types are not supported: Attached.IconData.
Я открыт для решения моей реализации, любого обходного пути или другого решения.





<Path Name = "Icon" Stroke = "Black" StrokeThickness = "1" Stretch = "Uniform"
Data = "{Binding (local:Attached.IconData.Geometry), RelativeSource = {RelativeSource TemplatedParent}}"/>
Здесь (local:Attached.IconData.Geometry) означает вложенный тип. Чтобы получить свойство объекта Attached.IconData, необходимо использовать следующий путь привязки:
<Path Name = "Icon" Stroke = "Black" StrokeThickness = "1" Stretch = "Uniform"
Data = "{Binding (local:Attached.IconData).Geometry, RelativeSource = {RelativeSource TemplatedParent}}"/>
Также не забудьте изменить присоединенный тип свойства с Geometry на IconData в типе Attached.
Класс IconData не должен быть вложен в какой-либо тип, потому что это именно то, что считается не поддерживаемым (просто поместите в то же пространство имен, что и другие используемые типы).
После этих модификаций ваш код начал у меня работать.
Вот главное окно XAML:
<Window x:Class = "WpfApplication1.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local = "clr-namespace:WpfApplication1"
Title = "MainWindow" Height = "250" Width = "260">
<Window.Resources>
<ResourceDictionary>
<local:IconData x:Key = "ArrowUp" Fill = "False" Geometry = "M0,0 M10,10 M4.8,9 4.8,3 4.2,3 5,2 5.8,3 5.2,3 5.2,9 Z"/>
<ControlTemplate x:Key = "ButtonTemplate" TargetType = "{x:Type Button}">
<Viewbox>
<Path Name = "Icon" Stretch = "Uniform"
Data = "{Binding (local:Attached.IconPath).Geometry, RelativeSource = {RelativeSource TemplatedParent}}">
<Path.Style>
<Style TargetType = "Path">
<Style.Triggers>
<DataTrigger Binding = "{Binding (local:Attached.IconPath).Fill, RelativeSource = {RelativeSource TemplatedParent}}"
Value = "True">
<Setter Property = "Fill" Value = "Black" />
</DataTrigger>
<DataTrigger Binding = "{Binding (local:Attached.IconPath).Fill, RelativeSource = {RelativeSource TemplatedParent}}"
Value = "False">
<Setter Property = "Stroke" Value = "Black" />
<Setter Property = "StrokeThickness" Value = "0.2" />
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
</Viewbox>
</ControlTemplate>
</ResourceDictionary>
</Window.Resources>
<Button local:Attached.IconPath = "{StaticResource ArrowUp}" Template = "{StaticResource ButtonTemplate}" />
</Window>
Обратите внимание, что я изменил геометрию пути на M0,0 M10,10 M4.8,9 4.8,3 4.2,3 5,2 5.8,3 5.2,3 5.2,9 Z, чтобы сделать его замкнутым и, таким образом, подходящим для заливки.
Вот скриншоты кейсов <local:IconData Fill = "False" ... /> и <local:IconData Fill = "True" ... />:
Он строится, но я почему-то не вижу пути. Вы зашли так далеко?