如何在 UWP 中使用资源字典中的路径数据
How to use a path data from a resource dictionary in UWP
这是微不足道的事情,但它不起作用。
我有这样的东西(在它自己的文件夹里)
<ResourceDictionary>
<Path x:Key="Test"
Stroke="Black"
Fill="Gray"
Data="M 10,100 C 10,300 300,-200 300,100" />
</ResourceDictionary>
现在我想用它
<Page>
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergeDictionaries>
<ResourceDictionary Source="MyFolder/MyResourceDictionary.xaml/>
</ResourceDictionary.MergeDictionaries>
</ResourceDictionary>
</Page.Resources>
<ContentPresenter Content="{StaticResource Test}"/>
<Page/>
这会抛出异常,但我不明白为什么。在 wpf 中完全相同的场景工作正常。
这个解决方案怎么样?
声明你的GeometryData
<x:String x:Key="TestPathGeomerty">M 10,100 C 10,300 300,-200 300,100</x:String>
并使用 Path
,而不是 ContentPresenter
<Path Data="{StaticResource TestPathGeomerty}"
Fill="Red"/>
在 WPF 中,您可以在多个控件中共享同一个实例。不幸的是,这在 UWP 中是不可能的。
保证在 UWP 中工作的唯一解决方案是在包含图标的资源中定义一个 DataTemplate。
使用PathIcon 代替Path 也更好。 PathIcon 使用将从您的父控件继承的前景 属性。
下面是一个示例,说明如何为自动缩放的图标共享数据路径(通过使用 Viewbox)。
<Page.Resources>
<DataTemplate x:Key="MagnifyingGlassPathIconCT">
<Viewbox Stretch="Uniform">
<PathIcon Data="M44,12 C32,12 22,22 22,34 22,46 32,56 44,56 56,56 66,46 66,34 66,22 56,12 44,12z M44,0 C63,0 78,15 78,34 78,53 63,68 44,68 40,68 36.5,67.5 33,66 L32.5,66 14,90 0,79.5 18,55.5 17,55 C13,49 10,42 10,34 10,15 25,0 44,0z" />
</Viewbox>
</DataTemplate>
</Page.Resources>
<StackPanel Padding="40" HorizontalAlignment="Left">
<!-- Plain icon -->
<ContentPresenter
Width="40"
Height="40"
ContentTemplate="{StaticResource MagnifyingGlassPathIconCT}"
Foreground="Purple" />
<!-- Icon with a border -->
<Border
Width="40" Padding="7"
Height="40"
BorderBrush="Black"
BorderThickness="2">
<ContentPresenter ContentTemplate="{StaticResource MagnifyingGlassPathIconCT}" Foreground="Red" />
</Border>
<!-- Icon in a normal Button -->
<Button
Width="40"
Height="40"
ContentTemplate="{StaticResource MagnifyingGlassPathIconCT}"
Foreground="RoyalBlue" />
<!-- Icon in an AppBarButton -->
<AppBarButton
Width="40"
ContentTemplate="{StaticResource MagnifyingGlassPathIconCT}"
Foreground="Black"
Label="Search" />
</StackPanel>
对于允许您在样式中定义它的解决方案,请尝试像这样编写附加的 属性:
public static string GetPathData(DependencyObject obj)
{
return (string)obj.GetValue(PathDataProperty);
}
public static void SetPathData(DependencyObject obj, string value)
{
obj.SetValue(PathDataProperty, value);
}
public static readonly DependencyProperty PathDataProperty =
DependencyProperty.RegisterAttached("PathData", typeof(string), typeof(ElementExtensions), new PropertyMetadata(null, (d, e) =>
{
if (d is Path path)
{
Binding b = new Binding { Source = e.NewValue };
path.SetBinding(Path.DataProperty, b);
}
}));
现在您可以像这样定义样式了:
<Style x:Key="BasePathStyle" TargetType="Path">
<Setter Property="e:ElementExtensions.PathData" Value="M 10,100 C 10,300 300,-200 300,100" />
</Style>
然后像这样使用它:
<Path Style="{StaticResource BasePathStyle}" />
Path.Data 属性 是 Geometry
类型,因此将其定义为 Geometry
而不是 string
<Geometry x:Key="TestPathGeomerty">M 10,100 C 10,300 300,-200 300,100</Geometry>
<Path Data="{StaticResource TestPathGeomerty}"
Fill="Red"/>
这是微不足道的事情,但它不起作用。
我有这样的东西(在它自己的文件夹里)
<ResourceDictionary>
<Path x:Key="Test"
Stroke="Black"
Fill="Gray"
Data="M 10,100 C 10,300 300,-200 300,100" />
</ResourceDictionary>
现在我想用它
<Page>
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergeDictionaries>
<ResourceDictionary Source="MyFolder/MyResourceDictionary.xaml/>
</ResourceDictionary.MergeDictionaries>
</ResourceDictionary>
</Page.Resources>
<ContentPresenter Content="{StaticResource Test}"/>
<Page/>
这会抛出异常,但我不明白为什么。在 wpf 中完全相同的场景工作正常。
这个解决方案怎么样?
声明你的GeometryData
<x:String x:Key="TestPathGeomerty">M 10,100 C 10,300 300,-200 300,100</x:String>
并使用 Path
,而不是 ContentPresenter
<Path Data="{StaticResource TestPathGeomerty}"
Fill="Red"/>
在 WPF 中,您可以在多个控件中共享同一个实例。不幸的是,这在 UWP 中是不可能的。
保证在 UWP 中工作的唯一解决方案是在包含图标的资源中定义一个 DataTemplate。
使用PathIcon 代替Path 也更好。 PathIcon 使用将从您的父控件继承的前景 属性。
下面是一个示例,说明如何为自动缩放的图标共享数据路径(通过使用 Viewbox)。
<Page.Resources>
<DataTemplate x:Key="MagnifyingGlassPathIconCT">
<Viewbox Stretch="Uniform">
<PathIcon Data="M44,12 C32,12 22,22 22,34 22,46 32,56 44,56 56,56 66,46 66,34 66,22 56,12 44,12z M44,0 C63,0 78,15 78,34 78,53 63,68 44,68 40,68 36.5,67.5 33,66 L32.5,66 14,90 0,79.5 18,55.5 17,55 C13,49 10,42 10,34 10,15 25,0 44,0z" />
</Viewbox>
</DataTemplate>
</Page.Resources>
<StackPanel Padding="40" HorizontalAlignment="Left">
<!-- Plain icon -->
<ContentPresenter
Width="40"
Height="40"
ContentTemplate="{StaticResource MagnifyingGlassPathIconCT}"
Foreground="Purple" />
<!-- Icon with a border -->
<Border
Width="40" Padding="7"
Height="40"
BorderBrush="Black"
BorderThickness="2">
<ContentPresenter ContentTemplate="{StaticResource MagnifyingGlassPathIconCT}" Foreground="Red" />
</Border>
<!-- Icon in a normal Button -->
<Button
Width="40"
Height="40"
ContentTemplate="{StaticResource MagnifyingGlassPathIconCT}"
Foreground="RoyalBlue" />
<!-- Icon in an AppBarButton -->
<AppBarButton
Width="40"
ContentTemplate="{StaticResource MagnifyingGlassPathIconCT}"
Foreground="Black"
Label="Search" />
</StackPanel>
对于允许您在样式中定义它的解决方案,请尝试像这样编写附加的 属性:
public static string GetPathData(DependencyObject obj)
{
return (string)obj.GetValue(PathDataProperty);
}
public static void SetPathData(DependencyObject obj, string value)
{
obj.SetValue(PathDataProperty, value);
}
public static readonly DependencyProperty PathDataProperty =
DependencyProperty.RegisterAttached("PathData", typeof(string), typeof(ElementExtensions), new PropertyMetadata(null, (d, e) =>
{
if (d is Path path)
{
Binding b = new Binding { Source = e.NewValue };
path.SetBinding(Path.DataProperty, b);
}
}));
现在您可以像这样定义样式了:
<Style x:Key="BasePathStyle" TargetType="Path">
<Setter Property="e:ElementExtensions.PathData" Value="M 10,100 C 10,300 300,-200 300,100" />
</Style>
然后像这样使用它:
<Path Style="{StaticResource BasePathStyle}" />
Path.Data 属性 是 Geometry
类型,因此将其定义为 Geometry
而不是 string
<Geometry x:Key="TestPathGeomerty">M 10,100 C 10,300 300,-200 300,100</Geometry>
<Path Data="{StaticResource TestPathGeomerty}"
Fill="Red"/>