c# - listboxitem wpf
¿Cómo obtener el índice del ítem ItemsControl actual? (3)
¿Hay alguna forma de obtener el índice del elemento ItemsControl
actual en WPF
?
Por ejemplo, quiero hacer algo como:
<ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding current_index}">
</TextBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
para que después de esto, el primer TextBox
muestre el texto "0"
, el segundo "1"
, el tercero "2" ...
Mira esto
<ItemsControl ItemsSource="{Binding Items}" Name="lista">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource converter}">
<Binding Path="."/>
<Binding ElementName="lista" Path="ItemsSource"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
El convertidor se ve así
public class conv : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ObservableCollection<string> lista = (ObservableCollection<string>)values[1];
return String.Concat(lista.IndexOf(values[0].ToString()), " ", values[0].ToString());
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Como resultado
Aquí cómo obtengo ItemIndex
<ItemsControl>
<ItemsControl.Resources>
<CollectionViewSource x:Key="ProductItems" Source="{Binding SelectedScanViewModel.Products}">
<CollectionViewSource.SortDescriptions>
<componentModel:SortDescription PropertyName="ProductName" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</ItemsControl.Resources>
<ItemsControl.ItemsSource>
<Binding Source="{StaticResource ProductItems}"/>
</ItemsControl.ItemsSource>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="{Binding ProductName}" HorizontalAlignment="Center" />
<TextBox Name="txtFocus" Text="{Binding Qty}" MinWidth="80" HorizontalAlignment="Center"
behaviors:SelectTextOnFocus.Active="True">
<TextBox.TabIndex>
<MultiBinding Converter="{StaticResource GetIndexMultiConverter}" ConverterParameter="0">
<Binding Path="."/>
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" Path="ItemsSource"/>
</MultiBinding>
</TextBox.TabIndex>
</TextBox>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding SelectedScanViewModel.Products.Count}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Y el convertidor:
public class GetIndexMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var collection = (ListCollectionView)values[1];
var itemIndex = collection.IndexOf(values[0]);
return itemIndex;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException("GetIndexMultiConverter_ConvertBack");
}
}
De esta forma, puede vincular todo tipo de colección a ItemSource y se cambiará a ListCollectionView. Entonces, el convertidor funcionará para diferentes tipos de colección.
xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Sugeriría mirar:
Elementos de WPF Controle el índice de ListItem actual en ItemsSource
Explica cómo evitar el hecho de que no existe una propiedad Index incorporada en ItemsControl.
EDITAR:
Probé el siguiente código:
<Window.Resources>
<x:Array Type="{x:Type sys:String}" x:Key="MyArray">
<sys:String>One</sys:String>
<sys:String>Two</sys:String>
<sys:String>Three</sys:String>
</x:Array>
</Window.Resources>
<ItemsControl ItemsSource="{StaticResource MyArray}" AlternationCount="100" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource TemplatedParent},
StringFormat={}Index is {0}}">
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl >
Y obtenga una ventana con tres TextBlocks como:
[Index is 0]
[Index is 1]
[Index is 2]