Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specify datacontext type on listbox ItemContainer in style

In a ListBox I have a ItemContainer's IsSelected property bound to my ViewModel's IsSelected property using <ListBox.ItemContainerStyle> syntax.

It works fine, but I get a Resharper warning:

Cannot resolve property 'IsSelected' in data context of type "FooSolution.BarViewModel".

How do I specify specify DataContext type on ListBox ItemContainer to get rid of this warning?

Here is the code. I have a BarViewModel class:

public ObservableCollection<FooViewModel> FooItems { get;set; }

BarViewModel is assigned to DataContext in the Control which contains the ListBox

and FooViewModel as follows:

public bool IsSelected
{
    get
    {
        return isSelected;
    }

    set
    {
        if (isSelected == value)
        {
            return;
        }

        isSelected = value;
        RaisePropertyChanged(() => IsSelected);
    }
}

and XAML like this:

<ListBox ItemsSource="{Binding FooItems}" SelectionMode="Multiple">        
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

Update I've tried setting d:DataContext using a setter, as suggested by HighCore, but unfortunatelly, it doesn't help and even breaks the build:

<Setter Property="d:DataContext" Value="{d:DesignInstance yourxmlns:yourItemViewModelClass}"/>

(Throws: Error 1 The tag 'DesignInstance' does not exist in XML namespace 'schemas.microsoft.com/expression/blend/2008';. Line 31 Position 50. )

Update 2 Finaly, the solution is to set d:DataContext on the style element itself (see my answer bellow):

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}" d:DataContext="{d:DesignInstance local:FooViewModel }">
        <Setter Property="IsSelected" Value="{Binding IsSelected}" />
    </Style>

like image 247
Isantipov Avatar asked Mar 05 '13 18:03

Isantipov


3 Answers

As pointed out by @HighCore the solution is to specify d:DataContext attribute from blend SDK, however, it worked only when set on a Style element itsself, not in the property setter:

<ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}" d:DataContext="{d:DesignInstance local:FooViewModel }">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
</ListBox.ItemContainerStyle>

This removes Resharper's warning and also changes binding Path when property is renaimed on the ViewModel. Cool!

like image 179
Isantipov Avatar answered Oct 20 '22 10:10

Isantipov


Specifying d:DataContext="{d:DesignInstance nmspc:Clz}" with other attributes of Style tag didn't help me: R# / IntelliSense really stopped highlighting properties I was binding to but the designer also showed me an error message instead of the view.

The trick I found out is to specify <d:Style.DataContext> inside the Style tag. And it appeared to be so universal that it answers another question, about using interfaces as d:DataContext.

Here is my answer to that question with a small example: https://stackoverflow.com/a/46637478/5598194

like image 8
N. Kudryavtsev Avatar answered Oct 20 '22 10:10

N. Kudryavtsev


use d:DataContext like this:

<Setter Property="d:DataContext" Value="{d:DesignInstance yourxmlns:yourItemViewModelClass}"/>

You also need the following xmlnses added to the root element:

     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d"
like image 3
Federico Berasategui Avatar answered Oct 20 '22 10:10

Federico Berasategui