How to properly bind to a property in ViewModel from data template

Introduction

Often we face a situation where we have defined a DataTemplate and we need to bind to a property, most often to a Command in ViewModel. To achieve this we will define the binding and will set a RelativeSource for that binding which in some cases can ends up in an error like this. BindingExpression path error: … property not found on ‘object’ … BindingExpression:Path=… DataItem=…

<Window.Resources>
        <DataTemplate x:Key="TestTemplate">
            <DockPanel>
                <Label Content="{Binding}" />
                <Button Command="{Binding CommandHandler, RelativeSource={RelativeSource AncestorType=Grid}}" />
            </DockPanel>
        </DataTemplate>
</Window.Resources>
<Grid>
    <ItemsControl ItemTemplate="{StaticResource TestTemplate}" ItemsSource="{Binding Values}" />
</Grid>

In most of the situation, the binding which is shown above works, but in certain situation like this example, this will fail to bind and if you examine the output window in visual studio, you can see a similar error as below.

BindingExpression path error: […] property not found on ‘object’ […] BindingExpression:Path=[…] DataItem=…

Here in this example, the exact error which you will get is:-

System.Windows.Data Error: BindingExpression path error: ‘CommandHandler’ property not found on ‘object’ ‘‘Grid’ (Name=’’)’. BindingExpression:Path=CommandHandler; DataItem=’Grid’ (Name=’’); target element is ‘Button’ (Name=’’); target property is ‘Command’ (type ‘ICommand’)

How did I fix this?

This happens because, when we define a RelativeSource, WPF tries to resolve the property which we are binding, from the object it finds up in the hierarchy whose type is equal to the type which we have defined for AncestorType. Here the relative source is Grid and Grid object does not have a property called CommandHandler, this is exactly what the error says.

Now if we examine, the Grid object has a property called DataContext, which is set or inherited from its parent to as the ViewModel, and the ViewModel has the property which we need. So a simple fix is to say DataContext.CommandHandler which binds to the CommandHandler property in ViewModel. The final binding is as shown below.

<Window.Resources>
    <DataTemplate x:Key="TestTemplate">
        <DockPanel>
            <Label Content="{Binding}"/>
            <Button Command="{Binding DataContext.CommandHandler,RelativeSource={RelativeSource AncestorType=Grid}}" />
        </DockPanel>           
    </DataTemplate>
</Window.Resources>

<Grid>
    <ItemsControl ItemsSource="{Binding Values}" ItemTemplate="{StaticResource TestTemplate}" />
</Grid>

Delphi how to check if you have read permission on a directory

It seems to be difficult to check the read permission on a directory in Delphi 2009. Here we will see how to find the read permission in an alternate way. Continue reading

Libish Varghese Jacob

Libish Varghese JacobI am currently working as a lead engineer in one of the leading wind turbine manufacturing firm. I have wide range of interests and getting my hands dirty in technology is one among them. I use this platform primarily as my knowledge base. I also use this platform to share my experience and experiments so that it might help someone who is walking the way I already did. The suggestions expressed here are the best to my knowledge at the time of writing and this may not necessarily be the best possible solution. I would pretty much appreciate if you could comment on it to bring into my notice on what could have been done better.