There are a few options for this; I'll name a few:
- An 'set-once' index property in the item ViewModel. When creating the list in the viewmodel, also set the index for each item ViewModel. (e.g. with a for-loop and an iterator). You can then bind to that index property. Downside is that changes in the list are not reflected on the index.
for (int i = 0; i < Parent.Childs.Count; i++)
{
string child = (string)Parent.Childs[i];
Childs.Add(new ChildViewModel(i, child));
}
with
public class ChildViewModel
{
public int Index { get; set; }
...
}
- A 'live' index property. Pass the containing list into the ViewModel and add a property with a getter that returns 'Parent.IndexOf(this)'. But you need some way of raising PropertyChanged for the Index when the collection changes. Using an ObservableCollection and subscribing to CollectionItemsChanged would be one way to achieve that.
foreach (var item in Parent.Childs)
{
Childs.Add(new ChildViewModel(Parent.Childs, child));
}
with
public class ChildViewModel
{
public int Index { get; } => Parent.IndexOf(this);
...
public ChildViewModel(IList<Child> parent)
{
if (parent is INotifyCollectionChanged p)
p.CollectionChanged += ParentCollectionChanged;
}
private void ParentCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
NotifyPropertyChanged(nameof(Index));
}
}
- Binding the item and using a ValueConverter taking the list as the converter parameter. Again using IndexOf(...)
- Binding the collection and using a ValueConverter taking the item as the converter parameter. Again using IndexOf(...)
One example of the valueconverter taking the item is given in this answer: https://stackoverflow.com/a/662232/11201993 this does not require you to add fields to the viewmodel.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…