Wpf ICollectionView绑定项无法解析对象类型的属性

时间:2013-11-27 22:55:10

标签: c# wpf xaml icollectionview

我已在XAML设计器中绑定GridView ICollectionView,但未知属性,因为CollectionView中的实体已转换为Object类型且实体属性无法访问,它运行正常没有错误但设计师将其显示为错误,如果我绑定到集合我可以访问属性

示例实体是具有Person属性的string Name我将它们放在ObservableCollection<Person>中并从中获取视图并将其绑定到GridView.ItemsSource现在当我尝试设置列标题DataMemberBinding.FirstName属性,设计者将其显示为错误

  

无法在类型对象

的数据上下文中解析属性'FirstName'

这是一个错误还是Resharper在我身上耍花招

示例代码:

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>

enter image description here

3 个答案:

答案 0 :(得分:6)

Resharper在XAML视图中提供的警告是因为控件的设计时视图不知道它的数据上下文是什么类型。您可以使用d:DesignInstance来帮助您进行绑定。

添加以下内容(适当替换Assembly / Namespace / Binding Target名称)

<UserControl x:Class="MyNamespace.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup‐compatibility/2006"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:lcl="clr‐namespace:MyAssembly"
d:DataContext="{d:DesignInstance Type=lcl:ViewModel}">

答案 1 :(得分:0)

您可以创建ICollectionView的通用版本,并将其用于您的PersonCollection属性,如本帖子https://benoitpatra.com/2014/10/12/a-generic-version-of-icollectionview-used-in-a-mvvm-searchable-list/所示。

答案 2 :(得分:0)

都不 d:DataContext =“ {d:DesignInstance Type = lcl:ViewModel}”> 也不 GenericCollectionView 直接用于具有CollectionViewSource的DataGrid。

    <DataGrid AutoGenerateColumns="False"
              ItemsSource="{Binding collectionViewSource.View}" 
              SelectedItem="{Binding SelectedRow}" 

我们无法设置“ d:DataContext”;因为,我们经常需要将多个属性绑定到我们的视图模型。

CollectionViewSource创建一个新的ListCollectionView,每次您设置Source属性时都会实例化运行时。由于设置Source属性是刷新一系列行的唯一合理方法,因此我们无法保留GenericCollectionView。

我的解决方案也许很明显,但是我转储了CollectionViewSource。通过创建属性

private ObservableCollection<ListingGridRow> _rowDataStoreAsList;
public GenericCollectionView<ListingGridRow> TypedCollectionView
{
  get => _typedCollectionView;
  set { _typedCollectionView = value; OnPropertyChanged();}
}

public void FullRefresh()
{
    var listData = _model.FetchListingGridRows(onlyListingId: -1);
    _rowDataStoreAsList = new ObservableCollection<ListingGridRow>(listData);
    var oldView = TypedCollectionView;
    var saveSortDescriptions = oldView.SortDescriptions.ToArray();
    var saveFilter = oldView.Filter;
    TypedCollectionView = new GenericCollectionView<ListingGridRow>(new ListCollectionView(_rowDataStoreAsList));
    var newView = TypedCollectionView;
    foreach (var sortDescription in saveSortDescriptions)
    {
        newView.SortDescriptions.Add(new SortDescription()
        {
            Direction = sortDescription.Direction,
            PropertyName = sortDescription.PropertyName
        });
    }
    newView.Filter = saveFilter;
}
internal void EditItem(object arg)
{
    var view = TypedCollectionView;
    var saveCurrentPosition = view.CurrentPosition;
    var originalRow = view.TypedCurrentItem;
    if (originalRow == null)
        return;
    var listingId = originalRow.ListingId;
    var rawListIndex = _rowDataStoreAsList.IndexOf(originalRow);
    // ... ShowDialog ... DialogResult ...
    var lstData = _model.FetchListingGridRows(listingId);
    _rowDataStoreAsList[rawListIndex] = lstData[0];
    view.MoveCurrentToPosition(saveCurrentPosition);
    view.Refresh();
}

添加后     公共T TypedCurrentItem =>(T)collectionView.CurrentItem; 到Maxence提供的GenericCollectionView。