2014-03-13 61 views
14

有没有什么办法可以获得当前ItemsControl项目的索引WPF如何获取当前ItemsControl项目的索引?

例如,我想要做的事,如:

<ItemsControl> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <TextBox Text="{Binding current_index}"> 
      </TextBox> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

所以在此之后,第一TextBox会显示文字"0",第二"1",第三"2" ...

+0

可能重复的[WPF ItemsControl的当前列表项中的索引的ItemsSource](http://stackoverflow.com/questions/6511180/wpf-itemscontrol-the-current-listitem-index-in-the-itemssource ) – har07

回答

25

我建议看:

WPF ItemsControl the current ListItem Index in the ItemsSource

它说明了如何解决的事实,没有一个建在ItemsControl的索引属性。

编辑:

我尝试下面的代码:

<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 > 

,并得到一个窗口有三个的TextBlocks这样的:

[Index is 0] 
[Index is 1] 
[Index is 2] 
+1

对于其他谁找到这个,我喜欢和使用Saykor的解决方案。我听说你不能总是从零开始依靠AlternationCount。感觉像一个黑客。而是使用转换器并将确定索引所需的信息传递给它。 – Skychan

+1

@Skychan你能否提供更多的参数,为什么用这种方式的AlternationCount应该是不可靠的? – Leonidas

6

检查了这一点

<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> 

转换器看起来像这样

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(); 
    } 
} 

结果 enter image description here

+1

请注意,只有在视图与原始来源完全匹配时才有效,即不会对其进行排序或过滤。 –

3

在这里,我怎么弄的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> 

和转换器:

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"); 
    } 
} 

通过这种方式,您可以将每种类型的集合绑定到ItemSource,并且他将更改为ListCollectionView。所以转换器将适用于不同的收集类型。

xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase" 
+0

这是一个类似的替代解决方案,它使用ItemContainerGenerator来确定索引。 http://stackoverflow.com/questions/7290147/is-possible-to-get-a-index-from-a-item-in-a-list – Skychan

+0

我认为这种方法将无法正常工作:IndexOf使用Equals如果源集合有重复(例如两个相同的字符串值),IndexOf将始终返回第一个项目。 – aderesh

+0

我认为使用ItemContainerGenerator的解决方案更好。谢谢。 – aderesh

相关问题