[英]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.