I have bound a GridView
with an ICollectionView
in the XAML designer the properties are not known because the entity in the CollectionView
have been transformed into type Object
and the entity properties can't be accessed, it runs fine no error but the designer shows it as an error, if I bind to the collection I can access the properties fine
Example the entity is a Person
with a string Name
property I place them in an ObservableCollection<Person>
and get the view from it and bind it to the GridView.ItemsSource
now when I try to set the column header DataMemberBinding.FirstName
property the designer shows it as an error
Cannot Resolve property 'FirstName' in data Context of type object
Is it a bug or is it Resharper playing tricks on me
Sample code:
public class Person
{
public string FirstName{
get { return _firstName; }
set { SetPropertyValue("FirstName", ref _firstName, value); }
}
}
public class DataService
{
public IDataSource DataContext { get; set; }
public ICollectionView PersonCollection{ get; set; }
public DataService()
{
DataContext = new DataSource();
//QueryableCollectionView is from Telerik
//but if i use any other CollectionView same thing
//DataContext Persons is an ObservableCollection<Person> Persons
PersonCollection = new QueryableCollectionView(DataContext.Persons);
}
}
<telerik:RadGridView x:Name="ParentGrid"
ItemsSource="{Binding DataService.PersonCollection}"
AutoGenerateColumns="False">
<telerik:RadGridView.Columns >
<telerik:GridViewDataColumn Header="{lex:Loc Key=FirstName}"
DataMemberBinding="{Binding FirstName}"/>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
The warnings that Resharper is giving you in the XAML view is because the design-time view of the control does not know what type it's data-context is. You can use a d:DesignInstance to help with your bindings.
Add the following (replacing Assembly/Namespace/Binding Target names appropriately)
Neither d:DataContext="{d:DesignInstance Type=lcl:ViewModel}"> nor GenericCollectionView works directly for a DataGrid with a CollectionViewSource.
We can't set "d:DataContext"; because, we often need to bind multiple properties to our viewmodel.
The CollectionViewSource creates new ListCollectionView which is runtime instantiated each time you set the Source property. Since setting the Source property is the only reasonable way to refresh a range of rows, we can't keep a GenericCollectionView around.
My solution is perhaps perfectly obvious, but I dumped the CollectionViewSource. By making creating a property
After adding public T TypedCurrentItem => (T)collectionView.CurrentItem; To the GenericCollectionView provided by Maxence.
Your entity has not been transformed in object, it's because the interface
ICollectionView
is not a generic collection so ReSharper has no way to know that it holds a collection ofPerson
.You can create a generic version of
ICollectionView
and use it for yourPersonCollection
property as demonstrated in this post https://benoitpatra.com/2014/10/12/a-generic-version-of-icollectionview-used-in-a-mvvm-searchable-list/.First an interface:
The implementation:
And finally the usage:
In the constructor: