UserControl在设计器中没有宽度渲染

时间:2017-04-14 19:38:27

标签: c# wpf xaml user-controls

我有一个包含路径元素的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)));
    }

1 个答案:

答案 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}}" />