数据上下文的自定义标记扩展始终作为类型System.Object处理

时间:2016-01-21 15:19:19

标签: c# wpf xaml markup-extensions

我正在尝试创建一个自定义XAML标记扩展,它将类型作为参数,并在运行时使用IoC容器解析该类型,但在设计时,只需使用默认构造函数创建它。现在,我只是想实现默认的构造函数部分。它看起来像这样:

<UserControl ...
             DataContext="{custom:MyCustomExtension MyType}"

    <TextBox Text="{Binding SomeProperty}" />
</UserControl>

问题是设计人员总是将我的扩展所产生的值视为类型对象,因此我无法使用GUI绑定工具,但它在运行时可以正常工作。

Binding Tools Failing

这是我重现问题的基本实现。

[MarkupExtensionReturnType(typeof(object))]
public class MyCustomExtension : MarkupExtension
{
    [ConstructorArgument("dataContextType")]
    public Type DataContextType { get; set; }

    public MyCustomExtension () {  }

    public MyCustomExtension (Type dataContextType)
    {
        DataContextType = dataContextType;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return Activator.CreateInstance(DataContextType);
    }
}

我尝试使用反射器来研究StaticResourceExtension如何做到这一点,因为虽然它也具有[MarkupExtensionReturnType(typeof(object))]属性,但VS设计者使用被引用资源的真实类型没有问题,但是使用那条路线找不到任何特别的东西。

1 个答案:

答案 0 :(得分:1)

我在Blend(Microsoft Blend for Visual Studio Professional 2015)中尝试了自定义标记扩展,它对我有用:

Working

此更改&#34;创建数据绑定&#34;窗口仅在重建后可见。

我的XAML:

<Window x:Class="DesignTimeTypedDataContext.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DesignTimeTypedDataContext"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{local:MyCustom {x:Type local:MainWindowViewModel}}">
    <Grid>
        <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="14.862,19.706,0,0" TextWrapping="Wrap" Text="{Binding Text}" VerticalAlignment="Top"/>
    </Grid>
</Window>

BTW,我想你知道这一点,但有d:DataContext给你设计时间DataContext而不影响运行时。

<Window x:Class="DesignTimeTypedDataContext.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DesignTimeTypedDataContext"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        d:DataContext="{d:DesignInstance {x:Type local:MainWindowViewModel}}">
    <Grid>
        <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="14.862,19.706,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top"/>
    </Grid>
</Window>

也许这不是一个答案,只是想我分享它,也许它有助于调试。现在至少知道你的代码的人适用于某些人:)