首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Wpf ICollectionView绑定项无法解析类型对象的属性

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

Stack Overflow用户
提问于 2013-11-27 22:55:10
回答 3查看 5.5K关注 0票数 13

我已经将GridView绑定到XAML设计器中的ICollectionView中,属性不知道,因为CollectionView中的实体已转换为Object类型,并且实体属性无法访问,它运行良好,没有错误,但设计器显示为错误,如果绑定到集合,则可以很好地访问属性。

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

无法在类型对象的数据上下文中解析属性“FirstName”

是窃听器还是Resharper在捉弄我

样本代码:

代码语言:javascript
运行
复制
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>

EN

回答 3

Stack Overflow用户

发布于 2014-06-29 18:22:04

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

添加以下内容(适当替换程序集/名称空间/绑定目标名称)

代码语言:javascript
运行
复制
<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}">
票数 8
EN

Stack Overflow用户

发布于 2019-01-23 11:22:06

您的实体尚未在对象中转换,这是因为接口ICollectionView不是泛型集合,因此ReSharper无法知道它持有Person的集合。

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

首先,一些接口:

代码语言:javascript
运行
复制
public interface ICollectionView<T> : IEnumerable<T>, ICollectionView
{
}

public interface IEditableCollectionView<T> : IEditableCollectionView
{
}

执行情况:

代码语言:javascript
运行
复制
public class GenericCollectionView<T> : ICollectionView<T>, IEditableCollectionView<T>
{
    readonly ListCollectionView collectionView;

    public CultureInfo Culture
    {
        get => collectionView.Culture;
        set => collectionView.Culture = value;
    }

    public IEnumerable SourceCollection => collectionView.SourceCollection;

    public Predicate<object> Filter
    {
        get => collectionView.Filter;
        set => collectionView.Filter = value;
    }

    public bool CanFilter => collectionView.CanFilter;

    public SortDescriptionCollection SortDescriptions => collectionView.SortDescriptions;

    public bool CanSort => collectionView.CanSort;

    public bool CanGroup => collectionView.CanGroup;

    public ObservableCollection<GroupDescription> GroupDescriptions => collectionView.GroupDescriptions;

    public ReadOnlyObservableCollection<object> Groups => collectionView.Groups;

    public bool IsEmpty => collectionView.IsEmpty;

    public object CurrentItem => collectionView.CurrentItem;

    public int CurrentPosition => collectionView.CurrentPosition;

    public bool IsCurrentAfterLast => collectionView.IsCurrentAfterLast;

    public bool IsCurrentBeforeFirst => collectionView.IsCurrentBeforeFirst;

    public NewItemPlaceholderPosition NewItemPlaceholderPosition
    {
        get => collectionView.NewItemPlaceholderPosition;
        set => collectionView.NewItemPlaceholderPosition = value;
    }

    public bool CanAddNew => collectionView.CanAddNew;

    public bool IsAddingNew => collectionView.IsAddingNew;

    public object CurrentAddItem => collectionView.CurrentAddItem;

    public bool CanRemove => collectionView.CanRemove;

    public bool CanCancelEdit => collectionView.CanCancelEdit;

    public bool IsEditingItem => collectionView.IsEditingItem;

    public object CurrentEditItem => collectionView.CurrentEditItem;

    public event NotifyCollectionChangedEventHandler CollectionChanged
    {
        add => ((ICollectionView) collectionView).CollectionChanged += value;
        remove => ((ICollectionView) collectionView).CollectionChanged -= value;
    }

    public event CurrentChangingEventHandler CurrentChanging
    {
        add => ((ICollectionView) collectionView).CurrentChanging += value;
        remove => ((ICollectionView) collectionView).CurrentChanging -= value;
    }

    public event EventHandler CurrentChanged
    {
        add => ((ICollectionView) collectionView).CurrentChanged += value;
        remove => ((ICollectionView) collectionView).CurrentChanged -= value;
    }

    public GenericCollectionView([NotNull] ListCollectionView collectionView)
    {
        this.collectionView = collectionView ?? throw new ArgumentNullException(nameof(collectionView));
    }

    public IEnumerator<T> GetEnumerator()
    {
        return (IEnumerator<T>) ((ICollectionView) collectionView).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((ICollectionView) collectionView).GetEnumerator();
    }

    public bool Contains(object item)
    {
        return collectionView.Contains(item);
    }

    public void Refresh()
    {
        collectionView.Refresh();
    }

    public IDisposable DeferRefresh()
    {
        return collectionView.DeferRefresh();
    }

    public bool MoveCurrentToFirst()
    {
        return collectionView.MoveCurrentToFirst();
    }

    public bool MoveCurrentToLast()
    {
        return collectionView.MoveCurrentToLast();
    }

    public bool MoveCurrentToNext()
    {
        return collectionView.MoveCurrentToNext();
    }

    public bool MoveCurrentToPrevious()
    {
        return collectionView.MoveCurrentToPrevious();
    }

    public bool MoveCurrentTo(object item)
    {
        return collectionView.MoveCurrentTo(item);
    }

    public bool MoveCurrentToPosition(int position)
    {
        return collectionView.MoveCurrentToPosition(position);
    }

    public object AddNew()
    {
        return collectionView.AddNew();
    }

    public void CommitNew()
    {
        collectionView.CommitNew();
    }

    public void CancelNew()
    {
        collectionView.CancelNew();
    }

    public void RemoveAt(int index)
    {
        collectionView.RemoveAt(index);
    }

    public void Remove(object item)
    {
        collectionView.Remove(item);
    }

    public void EditItem(object item)
    {
        collectionView.EditItem(item);
    }

    public void CommitEdit()
    {
        collectionView.CommitEdit();
    }

    public void CancelEdit()
    {
        collectionView.CancelEdit();
    }
}

最后,使用:

代码语言:javascript
运行
复制
ICollectionView<Person> PersonCollectionView { get; }

在构造函数中:

代码语言:javascript
运行
复制
var view = (ListCollectionView) CollectionViewSource.GetDefaultView(PersonCollection);
PersonCollectionView = new GenericCollectionView<Person>(view);
票数 1
EN

Stack Overflow用户

发布于 2019-11-17 16:23:16

d:DataContext="{d:DesignInstance Type=lcl:ViewModel}">和GenericCollectionView都不直接工作于带有CollectionViewSource的DataGrid。

代码语言:javascript
运行
复制
    <DataGrid AutoGenerateColumns="False"
              ItemsSource="{Binding collectionViewSource.View}" 
              SelectedItem="{Binding SelectedRow}" 

我们不能设置“d:DataContext”,因为我们通常需要将多个属性绑定到视图模型。

CollectionViewSource创建新的ListCollectionView,它在每次设置Source属性时都会实例化运行时。因为设置Source属性是刷新一系列行的唯一合理方法,所以我们不能保留一个GenericCollectionView。

我的解决方案也许是显而易见的,但我放弃了CollectionViewSource。通过创建一个属性

代码语言:javascript
运行
复制
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中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20254690

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档