2010-08-31 29 views
6

Với mã XAML sau đó với một ListControl như hành vi:WPF: Danh sách ràng buộc trong XAML - làm cách nào một mục có thể biết vị trí của nó trong danh sách?

<StackPanel> 
     <ItemsControl Name="_listbox" ItemsSource="{Binding ElementName=_userControl, Path=DataContext}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <DockPanel> 
         ... 
        </DockPanel> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </StackPanel> 

Kể từ danh sách có thể dài (100-200 bài), và các mặt hàng trông giống như, tôi nghĩ rằng nó sẽ hữu ích cho người dùng trong di chuyển nếu mọi mục sẽ hiển thị vị trí của chúng trong danh sách. Làm thế nào một mục trong mẫu có thể biết được vị trí của nó trong danh sách?

Trả lời

5

Đây là giải pháp hack. Chúng tôi có thể sử dụng Chuyển đổi giá trị với DataBinding. Vì vậy, bước đầu tiên là tuyên bố ValueConvertor của chúng tôi:

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 
    } 

Khai báo bất cứ nơi nào bạn muốn phương pháp tĩnh này để có được ListBox mẹ:

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

Sau đó, trong ListBox.Resources tuyên bố chuyển đổi của chúng tôi như sau:

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

Và cuối cùng - 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> 

Lưu ý: trong ví dụ này các mục sẽ được tính bắt đầu bằng 0 (không), bạn có thể thay đổi nó trong phương pháp chuyển đổi bằng cách thêm 1 vào kết quả.

Hope this helps ...

0

Theo MSDN Magazine bài viết "Charting with DataTemplates":

[...] các DataTemplate sẽ cần truy cập vào chỉ số của các mục dữ liệu đặc biệt trong bộ sưu tập. Nhưng thật dễ dàng để bao gồm thông tin này trong đối tượng kinh doanh [...]

Vì vậy, trừ khi có thay đổi trong .NET 4, không có thuộc tính "chỉ mục của mặt hàng này" trừ khi nó được bao gồm một cách rõ ràng trong mô hình.

Các vấn đề liên quan