問題描述
訪問 MarkupExtension.ProvideValue 中的構造函數參數 (Access to a constructor parameter within MarkupExtension.ProvideValue)
I have MyListYExtension markup extension that has no default constructor. Therefore it can be created with constructor syntax only. Another GetValueExtension markup extension tries to determine the target type of value asked so that it can do necessary conversion. For example, if you assign the value of the second extension to a property of type Double, GetValueExtension understands it and returns 2.0 instead of "2". Dummy example:
{MyListX Capacity={GetValue ListCapacityParam}}
Everything goes fine if I assign GetValueExtension to a property. Then the target type is accessible within MarkupExtension.ProvideValue via
((IProvideValueTarget)serviceProvider).TargetProperty.PropertyType
But when I apply GetValueExtension as a parameter for the constructor of MyListYExtension, then TargetProperty is null:
<!-- no default constructor in MyListY -->
<!-- the first parameter of MyListY is "int capacity" -->
{MyListY {GetValue ListCapacityParam}}
When XAML parser is assigning values to properties, it performs the default conversion. But it doesn't do it when it takes the value from markup extension. It results in an exception that it cannot assign e.g. string value to double property. To avoid that I try to emulate the default conversion but for that the target type needs to be known.
I cannot find any workaround to determine the actual type of the constructor parameter within MarkupExtension.ProvideValue call.
I can modify GetValueExtension but not MyListYExtension.
What can I do to solve this?
參考解法
方法 1:
It looks like a chicken and egg problem. The thing is that constructors can be overloaded and in order to find the suitable constructor, the framework needs to know the type of the parameter you are trying to pass into it.
In other words, at the time when the ProvideValue
is called it is not known what constructor will be used, hence it is not possible to provide the information about the target type.
(by Ivan Akcheurov、Pavlo Glazkov)