有一种方法可以在没有转换器的情况下执行此操作,并且能够在集合中包含重复项,但这意味着您必须维护一个有组织的列表,该列表还使用 KeyValuePair<int, T> 作为列表项类型来存储索引.
这是一个字符串列表的示例实现。它将显示按钮内的文本并将索引绑定到命令参数:
#region Items
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register("Items", typeof(ObservableCollection<string>), typeof(CulturePicker),
new FrameworkPropertyMetadata(new ObservableCollection<string>(),
FrameworkPropertyMetadataOptions.None,
new PropertyChangedCallback(OnItemsChanged)));
public ObservableCollection<string> Items
{
get { return (ObservableCollection<string>)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
private static void OnItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CulturePicker _this = (CulturePicker)d;
ObservableCollection<string> oldItems = (ObservableCollection<string>)e.OldValue;
ObservableCollection<string> newItems = _this.Items;
if (oldItems != null)
{
oldItems.CollectionChanged -= this.Items_CollectionChanged;
}
List<KeyValuePair<int, string>> organizedItems = new List<KeyValuePair<int, string>>();
for (int i = 0; i < newItems.Count; i++)
{
organizedItems.Add(new KeyValuePair<int, string>(i, newItems[i]));
}
this.OrganizedItems = organizedItems;
newItems.CollectionChanged += this.Items_CollectionChanged;
}
private void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
List<KeyValuePair<int, string>> organizedItems = new List<KeyValuePair<int, string>>();
for (int i = 0; i < e.NewItems.Count; i++)
{
organizedItems.Add(new KeyValuePair<int, string>(i, (string)e.NewItems[i]));
}
this.OrganizedItems = organizedItems;
}
#endregion
#region OrganizedItems
/// <summary>
/// OrganizedItems Dependency Property
/// </summary>
private static readonly DependencyProperty OrganizedItemsProperty =
DependencyProperty.Register("OrganizedItems", typeof(List<KeyValuePair<int, string>>), typeof(CulturePicker),
new FrameworkPropertyMetadata((List<KeyValuePair<int, string>>)null,
FrameworkPropertyMetadataOptions.None,
new PropertyChangedCallback(OnOrganizedItemsChanged)));
/// <summary>
/// Gets or sets the OrganizedItems property. This dependency property
/// indicates an organized dictionary with the index of the Items as key and the region itself as value.
/// </summary>
private List<KeyValuePair<int, string>> OrganizedItems
{
get { return (List<KeyValuePair<int, string>>)GetValue(OrganizedItemsProperty); }
set { SetValue(OrganizedItemsProperty, value); }
}
/// <summary>
/// Handles changes to the OrganizedItems property.
/// </summary>
private static void OnOrganizedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CulturePicker _this = (CulturePicker)d;
List<KeyValuePair<int, string>> oldOrganizedItems = (List<KeyValuePair<int, string>>)e.OldValue;
List<KeyValuePair<int, string>> newOrganizedItems = _this.OrganizedItems;
}
#endregion
<UserControl ...
Name="_">
...
<ItemsControl ItemsSource="{Binding OrganizedItems, ElementName=_}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding Command, ElementName=_}"
CommandParameter="{Binding Key}"
Text="{Binding Value}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
...
在 XAML 中,键是索引,值是实际项目,在本例中是字符串。 Command 属性本身不包含在此示例中。另请注意,它会在源列表发生任何更改时重新创建有组织的列表,这将触发重新渲染并导致大列表运行缓慢。