问题
I have a ViewModel which I'm using as an ItemsSource
for a ListView
, that implements an interface called ISelectable
:
/// <summary>
/// An interface that should be implemented by a ViewModel that can be
/// marked as selected, when multiple selections are allowed.
/// </summary>
public interface ISelectable
{
/// <summary>
/// Gets or sets a value indicating whether this instance is selected.
/// </summary>
/// <value>
/// <c>true</c> if this instance is selected; otherwise, <c>false</c>.
/// </value>
bool IsSelected { get; set; }
}
The ListView
is showing search results of a "search clients" feature, so all items are ClientViewModel
instances - and ClientViewModel
implements ISelectable
so has a IsSelected
property:
<ListView x:Name="SearchResultsList" ItemsSource="{Binding SearchResults}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type viewModels:ClientViewModel}">
<Label Content="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This works perfectly; in the window's ViewModel I can define a property like this:
public IEnumerable<ClientViewModel> SelectedClients
{
get
{
return _searchResults == null
? null
: _searchResults.Where(e => e.IsSelected);
}
}
And I get what I'm expecting.
The question I have is about the below part of the XAML - the designer underlines IsSelected
in the Value="{Binding}"
part and says "Cannot resolve property 'IsSelected' in data context of type [type of the window's ViewModel]":
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
</ListView.ItemContainerStyle>
- How can I tell the designer that the data context for
ListView.ItemContainerStyle
should be the same as that of the data template? - How does it end up working at run-time, if the XAML designer says it can't be resolved?
UPDATE
This is a ReSharper warning. I could switch it off, but what I want to know is how does the setter end up working, because I get correct auto-complete for this:
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type viewModels:ClientViewModel}">
<Label Content="{Binding Name}" /> <!-- "Name" is available from IntelliSense -->
</DataTemplate>
</ListView.ItemTemplate>
But not for that:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
<!-- "IsSelected" isn't, IntelliSense is showing the members of the Window's ViewModel -->
</Style>
</ListView.ItemContainerStyle>
回答1:
It should be the Resharper doing the trick as i never saw default designer intellisense pointing this type of error in Binding experssion. You can switch of the Resharper completly to proof it completly.
since you are setting property inside ListViewItem style and you are using {Binding IsSelected}, it will search IsSelected in the DataContext of each listviewitem which is your ClientViewModel and that has IsSelected property...hence binding is perfect.. the designer is not smart enough to prob this deep
来源:https://stackoverflow.com/questions/19100882/how-does-this-setter-end-up-working-listview-multiselect