Lennart
Lennart

Reputation: 10344

Can an ObjectDataProvider work with derived classes?

Let's say I have a base viewmodel for a specific control that implements some basic properties, e.g.

public abstract class ControlVmBase{

    public abstract int IconSize {get;set;}

}

I also have a ResourceDictionary which I want to use with that control, and ideally bind values in the contained styles to an implementation of ControlVmBase. I thought it would be a good idea to do this via an ObjectDataProvider, since it looks like a clean solution and gives me Intellisense support in the XAML:

<ResourceDictionary>
<ObjectDataProvider x:Key="LinkedVm" ObjectType="{x:Type ControlVmBase}" />

<Style x:Key="MySpecialControlStyle" TargetType="MyCustomControl">
    <Setter Property="ImageSize" Value="{Binding Source={StaticResource LinkedVm}, Path=IconSize}" />       
    </Style>

</ResourceDictionary>

However this doesn't work, since the ODP tries to instantiate ObjectType which is pointless, since it's an abstract class an doesn't affect the implemented classes. Is it possible to use an ODP like that, or is there another possibility to bind to derived classes?

Upvotes: 2

Views: 309

Answers (1)

Patrick Hofman
Patrick Hofman

Reputation: 157098

The problem is that you are using a base class, which doesn't work as you would expect. Since you don't know the type at design-time, you indeed have a problem.

So lets talk in solutions. In fact you don't have to mind to a type, you can bind to a method of a specific type too. That is nice, since you can now create a factory class, that picks the right type and returns an instance.

<ObjectDataProvider x:Key="odp"
                    ObjectType="{x:Type local:ControlVmBaseFactory}"
                    MethodName="GetInstance"
/>

You can also create a wrapper object where you pass in your type in the parameter, and let a method return an instance of it.

<ObjectDataProvider x:Key="odp"
                    ObjectType="{x:Type local:ControlWrapper}"
                    MethodName="GetInstance"
>
  <ObjectDataProvider.ConstructorParameters>
    <system:Type>Your.Class.Name</system:Type>
  </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>

Upvotes: 1

Related Questions