I want to create the ViewModel
of my WPF Application in the XAML code. It's easy if you just have the default constructor, but I need the View
as a Parameter, so I have to call the Constructor
myself.
This is as far as I came:
<ObjectDataProvider ObjectType="{x:Type local:ViewModel}">
<ObjectDataProvider.ConstructorParameters>
<Binding Source="{RelativeSource Self}"/>
</ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>
But with this there is an TargetInvocationException
thrown, because ConstrutorParameter
doesn't accept Binding
:
"Binding" can not be used within a ParameterCollection collection. "Binding" can only be set on a "DependencyProperty" of a "DependencyObject".
Is there any way to convert "Self" to an object or something?
Self already points to an object. Your problem in this case is that ParameterCollection isn't a DependencyObject, ie it is not derived from the DependencyObject class and does not implement its properties as DependencyProperties as per the DependencyObject implementation convention, just as the error message suggests. To work around this, you could wrap the class ObjectDataProvider into a wrapper class that implements DependencyObject and takes the values you give here as constructor parameters as DependencyProperties. Then you could pass "self" or any other resource to one of these properties and initialize the ObjectDataProvider inside your wrapper, passing the value of the property to the constructor of ObjectDataProvider.
class ObjectDataProviderWrapper : DependencyObject {
private ObjectDataProvider _objectDataProvider = null;
public static DependencyProperty ControlProperty = DependencyProperty.Register(.... (look that up in the manual, it depends on your use case)
public ObjectDataProvider DataProvider {
get {
if(_objectDataProvider == null) {
_objectDataProvider = new ObjectDataProvider(ControlProperty.GetValue(this));
}
return _objectDataProvider;
}
}
....
Using the ObjectDataProvider later on in your Xaml then would require one additional level of indirection, ie you will have to dereference your wrapper, which could be done using a DataContext scope like for example:
<Grid DataContext="{Binding Source={StaticResource wrapper}, Path=DataProvider}" >
...
</Grid>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.