繁体   English   中英

将ListView绑定到具有Converter的ICollectionView时,IsSynchronizedWithCurrentItem不起作用

[英]IsSynchronizedWithCurrentItem not working when ListView is bound to an ICollectionView with a Converter

我的ViewModel中有一个ICollectionView:

public class ContactsPanelViewModel : ViewModelBase
{
    private ICollectionView accountContactsView;
    public ICollectionView AccountContactsView
    {
        get => accountContactsView;
        set => NotifyPropertyChangedAndSet(ref accountContactsView, value);
    }
public ContactsPanelViewModel()
    {
        AccountContactsView = CollectionViewSource.GetDefaultView(G.AccountContacts); //G.AccountContacts is an IEnumarable<Contact> object
        AccountContactsView.SortDescriptions.Add(new SortDescription("FullName_LastNameFirst", ListSortDirection.Ascending));
        AccountContactsView.CurrentChanged += NewContactSelected;
        AccountContactsView.MoveCurrentToFirst();
    }
}

这是它绑定到的列表:

<ListView 
      x:Name="ContactList" 
      HorizontalAlignment="Left" 
      ItemsSource="{Binding Path=AccountContactsView, Converter={StaticResource ContactCardConverter}}"
      IsSynchronizedWithCurrentItem="True"/>

这是我创建的转换器:

public class ContactCardConverter : IValueConverter
{
    public object Convert(object Value, Type TargetType, object Parameter, CultureInfo Culture)
    {
        if (Value is ListCollectionView)
        {
            List<ContactCard> contactCards = new List<ContactCard>(); //ContactCard is a UserControl
            ListCollectionView data = Value as ListCollectionView;
            if (data.Count > 0 && data.GetItemAt(0) is Contact)
            {
                foreach(Contact contact in data)
                {
                    contactCards.Add(new ContactCard(contact));
                }
                return contactCards;
            }
            else
            {
                return null;
            }
        }
        else
        {
            return null;
        }
    }

    public object ConvertBack(object Value, Type TargetType, object Parameter, CultureInfo Culture)
    {
        if (Value is ContactCard)
        {
            return (Value as ContactCard).Contact;
        }
        else
        {
            return null;
        }
    }
}

问题是,因为我使用的是转换器,所以当ListView选择更改时, ICollectionViewCurrentItem不会同步。 转换器肯定是个问题,因为卸下转换器使其工作正常。

我添加了一个ConvertBack函数,以为如果使用了一个转换器,但是它不起作用,它将调用该函数。

从理论上讲,我可以将ICollectionView设置为ContactCard类型(这是一个UserControl),但这似乎不应该这样做,因为据我了解,ViewModel不应依赖于View的外观。 这也将增加一些兼容性,因为我需要使ICollectionView与我的Contact对象的实际集合保持同步。

当ListView使用转换器时,同步ListView和ICollectionView的正确方法是什么?

正确的方法是不要使用转换器。

您不应该将viewmodel-CollectionView转换为List (在您的情况下)或在转换器中转换为另一个CollectionView ,因为否则,如果在转换器中创建CollectionView,则将与转换器创建的集合中的视图(和IsSynchronizedWithCurrentItem正常)同步。 List无法同步,因为它没有实现IColectionView并且没有CurrentItem

正确的方法是不要使用转换器,将ContactCard -UserControl放入ListView.ItemTemplate

<ListView.ItemTemplate>
    <DataTemplate>
        <youCustomCtlNameSpace:ContactCard Contact="{Binding}"/>
     </DataTemplate>
</ListView.ItemTemplate>

如果您必须使用转换器,则IsSynchronizedWithCurrentItem没有意义,您必须通过将转换器绑定到ListView.SelectedItem来自己同步V和ListView.SelectedItem和您的Contact必须保留对UI对象的引用(如果符合MVVM,您对View没有依赖性,请参见: MVVM模式是否损坏? )。 但正如我已经指出的那样,这不是首选方法!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM