[英]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
选择更改时, ICollectionView
的CurrentItem
不会同步。 转换器肯定是个问题,因为卸下转换器使其工作正常。
我添加了一个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.