Using XamlReader for controls that does not have a default constructor

依然范特西╮ 提交于 2020-01-11 09:57:04

问题


I have some string representations of Xaml objects, and I want to build the controls. I'm using the XamlReader.Parse function to do this. For a simple control such as Button that has a default constructor not taking any parameters this works fine:

var buttonStr = "<Button xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">Text</Button>";
var button = (Button)XamlReader.Parse(buttonStr); 

However, when I try to do this to e.g. a Stroke control it fails. First trying a simple empty Stroke:

var strokeStr = "<Stroke xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"></Stroke>";
var stroke = (Stroke)XamlReader.Parse(strokeStr);

This gives the error:

Cannot create object of type 'System.Windows.Ink.Stroke'. CreateInstance failed, which can be caused by not having a public default constructor for 'System.Windows.Ink.Stroke'.

In the definition of Stroke I see that it needs at least a StylusPointsCollection to be constructed. I assume this is what the error is telling me, though was kinda assuming this would be handled by the XamlReader. Trying to transform a Xaml of Stroke with StylusPoints in it gives the same error:

var strokeStr = 
    "<Stroke xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">" + 
        "<Stroke.StylusPoints>" + 
            "<StylusPoint X=\"100\" Y=\"100\" />" +
            "<StylusPoint X=\"200\" Y=\"200\" />" + 
        "</Stroke.StylusPoints>" + 
    "</Stroke>";
var stroke = (Stroke) XamlReader.Parse(strokeStr);

What am I doing wrong? How do I tell the XamlReader how to create the Stroke correctly?


回答1:


It's a "feature" of the XAML language, it is declarative and doesn't know anything about constructors.

People use ObjectDataProvider in XAML to "translate" and wrap instances of classes that do not have a parameterless constructor (it's also useful for data binding).

In your case the XAML should look approximately like this:

<ObjectDataProvider ObjectType="Stroke">
    <ObjectDataProvider.ConstructorParameters>
        <StylusPointsCollection>
            <StylusPoint X="100" Y="100"/>
            <StylusPoint X="200" Y="200"/>
        </StylusPointsCollection>
    </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>

And the code should be:

var stroke = (Stroke) ((ObjectDataProvider)XamlReader.Parse(xamlStr)).Data;

HTH.



来源:https://stackoverflow.com/questions/2335900/using-xamlreader-for-controls-that-does-not-have-a-default-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!