WPF: Binding lists in XAML- how can an item know its position in the list?

后端 未结 3 422
不知归路
不知归路 2021-01-05 08:19

Given the following XAML code that with a ListControl like behavior:

    
        

        
相关标签:
3条回答
  • 2021-01-05 08:31

    This sample supports sorting:

    Numbered listbox

    0 讨论(0)
  • 2021-01-05 08:32

    According to MSDN Magazine article "Charting with DataTemplates":

    [...]the DataTemplate would need access to the index of the particular data item in the collection. But it's easy enough to include this information in the business object[...]

    So, unless there was a change in .NET 4, there is no "index of this item" property unless it is explicitly included in the model.

    0 讨论(0)
  • Here is a hack solution. We can use Value Conversion with DataBinding. So the first step is to declare our ValueConvertor:

    public class ListItemToPositionConverter : IValueConverter
        {
            #region Implementation of IValueConverter
    
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                var item = value as ListBoxItem;
                if (item != null)
                {
                    var lb = FindAncestor<ListBox>(item);
                    if (lb != null)
                    {
                        var index = lb.Items.IndexOf(item.Content);
                        return index;
                    }
                }
                return null;
            }            
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
    
            #endregion
        }
    

    Declare wherever you want this static method in order to obtain ListBox parent:

    public static T FindAncestor<T>(DependencyObject from) where T : class
            {
                if (from == null)
                    return null;
    
                var candidate = from as T;
                return candidate ?? FindAncestor<T>(VisualTreeHelper.GetParent(from));
            }
    

    Then in ListBox.Resources declare our convertor as follows:

    <ListBox.Resources>
                    <YourNamespace:ListItemToPositionConverter x:Key="listItemToPositionConverter"/>
                </ListBox.Resources>
    

    And finally - DataTemplate:

    <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Converter={StaticResource listItemToPositionConverter}}"/>
                            <Label Content="{Binding Path=DisplayName}"></Label>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
    

    Note: in this example the items will be numerated starting with 0 (zero), you can change it in Convert method by adding 1 to result.

    Hope this helps...

    0 讨论(0)
提交回复
热议问题