我有一个包含路径元素的UWP UserControl
,路径的Data
属性绑定到名为UserControl
的{{1}}的字符串属性。当我将控件添加到页面并将其Icon
属性设置为资源项时,控件不会呈现图标并且在设计器中具有0宽度。当我将应用程序部署到我的设备时,控件按预期呈现。有什么方法可以解决这个问题吗?
作为参考,我正在尝试构建一个包含大量可点击图标的简单工具栏。我确信还有其他方法可以实现这一点,但我正在使用它作为一种学习,因为我的XAML技能非常缺乏。我的代码可以在下面找到。
MainPage.xaml中
Icon
ActionIcon.xaml
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Stretch">
<local:ActionIcon IconData="{StaticResource Test}" ></local:ActionIcon>
</StackPanel>
ActionIcon.xaml.cs
<UserControl x:Name="userControl"
x:Class="UwpTest.ActionIcon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UwpTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="200"
d:DesignWidth="200">
<Viewbox Stretch="UniformToFill">
<Path Stretch="UniformToFill"
Data="{Binding IconData, ElementName=userControl}"
Fill="Black" />
</Viewbox>
</UserControl>
资源字典条目
public sealed partial class ActionIcon : UserControl
{
public ActionIcon()
{
InitializeComponent();
}
public string IconData
{
get
{
return (string) GetValue(IconDataProperty);
}
set
{
SetValue(IconDataProperty, value);
}
}
public static readonly DependencyProperty IconDataProperty = DependencyProperty.Register(
"IconData", typeof(string), typeof(ActionIcon), new PropertyMetadata(default(string)));
}
答案 0 :(得分:0)
简而言之,问题是IconData和Path.Data的类型不匹配。虽然IconData是一个字符串,但Path.Data想要一个Geometry。因此,如果要将路径的数据放在资源字典中,则其类型必须是Geometry或其子类之一。考虑一下,当绑定失败时,WPF不会抛出异常。而是在Visual Studio的输出窗口中收到消息。
但是当我直接设置Path.Data-Property时,为什么我可以使用字符串?
Path永远不会真正得到一个字符串。当XAML解析器获取属性的错误类型时,它会查看它所期望的类型的类。它在那里搜索TypeConversion-Attribute。当解析器查看Geometry时,它会找到这样一个属性:
[TypeConverter(typeof(GeometryConverter))]
abstract partial class Geometry
该属性指定TypeConverter。对于Geometry,它是GeomtryConverter,可以将字符串转换为Geometry。如果你想了解更多信息,请在msdn上发表一篇文章:How to: Implement a Type Converter
很好,但如何在ResourceDictionaries中使用Geomtries?
一旦您尝试创建路径而不将字符串设置为Path.Data,事情就会变得清晰。之前的简单贝塞尔曲线:
<Path Data="M 10,100 C 10,300 300,-200 300,100" />
之后:
<Path>
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="10,100">
<BezierSegment Point1="10,300" Point2="300,-200" Point3="300,100"/>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
TypeConverter产生这样的输出。只有TypeConverter再次转换点。但是,下一步很简单:只需将PathGeometry放在ResourceDictionary中。
作为一个小方节点:通过将用户控件DataContext设置为自身,可以避免对每个绑定使用ElementName:
<UserControl DataContext={Binding RelativeSource={RelativeSource Self}}" />