Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding works fine, but intellisense says: Cannot resolve property XXX in data context of type 'object'

I have a binding to a parent-element. How can I provide the data type for the DataContext in the binding, so intellisense can resolve the bound Properties?

The binding works fine at runtime. So, I have the following XAML structure:

<TabControl Name="TabDynamic" 
            ItemsSource="{Binding TabItems, Mode=OneWay}" ...>
    <TabControl.Resources>
        <DataTemplate x:Key="TabHeader" DataType="TabItem">
            <DockPanel>
                <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}" />
                <Button Command="{Binding ElementName=TabDynamic, Path=DataContext.DeleteTabCommand}"
                        CommandParameter="{Binding ElementName=TabDynamic, Path=DataContext.TabItems/}">
                    <Image Source="{DynamicResource DeleteImg}" Height="11" Width="11"></Image>
                </Button>
            </DockPanel>
        </DataTemplate>
        <DataTemplate x:Key="TabContent" DataType="viewModels:ConnectionInfoVM">
            <views:BufferViewerControl/>
        </DataTemplate>
    </TabControl.Resources>
</TabControl>

The data type of the DataContext is "viewModels:ConnectionInfoVM". Intellisense will now underline both Properties on the DataContext (so DeleteTabCommand and TabItems are underlined).

I already tried to use the design-time data-context definition "d:DataContext" within the Button element like so:

d:DataContext="{d:DesignInstance viewModels:ConnectionInfosVM}"

But this does not change the intellisense warnings.

I also tried to define the DataType on the DataTemplate to be "viewModels:ConnectionInfosVM", as I do for the content-template, but that too does not change the intellisense warnings (and I guess would be wrong, as the data type of the element really is a TabItem).

Another try was to define the DataContext by adding the following to the Button element definition:

<Button.DataContext>
    <viewModels:ConnectionInfosVM/>
</Button.DataContext>

But this too, does not get rid of the warnings.

like image 738
ptair Avatar asked Jul 05 '16 11:07

ptair


2 Answers

I needed to add the mc:Ignorable="d" attribute to the Window tag. Essentially I learned something new. The d: namespace prefix that Expression Blend/Visual Studio designer acknowledges is actually ignored/"commented out" by the real compiler/xaml parser!

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

The following was taken from

Nathan, Adam (2010-06-04). WPF 4 Unleashed (Kindle Locations 1799-1811). Sams. Kindle Edition.

Markup Compatibility

The markup compatibility XML namespace (http://schemas.openxmlformats.org/markup-compatibility/2006, typically used with an mc prefix) contains an Ignorable attribute that instructs XAML processors to ignore all elements/attributes in specified namespaces if they can’t be resolved to their .NET types/members. (The namespace also has a ProcessContent attribute that overrides Ignorable for specific types inside the ignored namespaces.)

Expression Blend takes advantage of this feature to do things like add design-time properties to XAML content that can be ignored at runtime.

mc:Ignorable can be given a space-delimited list of namespaces, and mc:ProcessContent can be given a space-delimited list of elements. When XamlXmlReader encounters ignorable content that can’t be resolved, it doesn’t report any nodes for it. If the ignorable content can be resolved, it will be reported normally. So consumers don’t need to do anything special to handle markup compatibility correctly.

like image 130
logeshpalani31 Avatar answered Sep 20 '22 19:09

logeshpalani31


I found a solution at least for the above described problem. I was setting the DataContext of the window in question in the code-behind. The TabControl in my example just inherits that DataContext, which is a ConnectionInfosVM.

In order to fix those warnings (and of course for the gained flexibility in providing a DataContext by a Locator), I defined the DataContext in XAML like so:

<UserControl ...
             DataContext="{Binding Source={StaticResource mainViewModelLocator}, Path=ConnectionInfosVM}">

It seems that intellisense is now able to resolve those references. But on the other side, I also changed the TextBlock contained within the DataTemplate to the following:

 <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=DataContext.Address}" />

Now the DataContext of such a TabItem is actually a different type, as it is the type of the backing object for the TabItem. So in this case, the Property Address cannot be found by intellisense.

So, the question kind of remains, is there a possibility to define the type of the DataContext within a binding defined in a DataTemplate?

like image 39
ptair Avatar answered Sep 18 '22 19:09

ptair