ItemsControlで現在のアイテムのインデックスを知ることは可能ですか?
[〜#〜] edit [〜#〜]これは機能します!
<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>
<StackPanel Margin="10">
<!-- one -->
<TextBlock Text="{Binding Path=.,
StringFormat={}Value is {0}}" />
<!-- two -->
<TextBlock Text="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource TemplatedParent},
FallbackValue=FAIL,
StringFormat={}Index is {0}}" />
<!-- three -->
<TextBlock Text="{Binding Path=Items.Count,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ItemsControl}},
StringFormat={}Total is {0}}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
次のようになります。
少し前に同じことを聞いた ここ
組み込みのIndexプロパティはありませんが、ItemsControlのAlternationCount
をアイテム数よりも大きい値に設定し、AlternationIndex
にバインドできます。
<TextBlock Text="{Binding
Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource Mode=TemplatedParent},
FallbackValue=FAIL,
StringFormat={}Index is {0}}" />
ListBoxが仮想化を ここで指摘されているbradgonesurfing として使用している場合、このソリューションは機能しない可能性があることに注意してください。
これは完全な答えではなく、提案です。提案されているようにAlternationIndex手法を使用しないでください。最初はうまくいくようですが、奇妙な副作用があります。 AlternationIndexが0から始まることを保証できないようです。
最初のレンダリングで正しく機能します
ただし、グリッドのサイズを変更してから展開すると、インデックスがゼロから始まらなくなります。下の画像で効果を見ることができます
これは、次のXAMLから生成されました。そこにはいくつかのカスタムコンポーネントがありますが、あなたはその考えを理解するでしょう。
<DataGrid
VirtualizingPanel.VirtualizationMode="Recycling"
ItemsSource="{Binding MoineauPumpFlanks.Stator.Flank.Boundary, Mode=OneWay}"
AlternationCount="{Binding MoineauPumpFlanks.Stator.Flank.Boundary.Count, Mode=OneWay}"
AutoGenerateColumns="False"
HorizontalScrollBarVisibility="Hidden"
>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Id">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Margin="0,0,5,0"
TextAlignment="Right"
Text="{Binding RelativeSource={ RelativeSource
Mode=FindAncestor,
AncestorType=DataGridRow},
Path=AlternationIndex}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn >
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Point ["/>
<Controls:DisplayUnits DisplayUnitsAsAbbreviation="True" DisplayUnitsMode="Length"/>
<TextBlock Text="]"/>
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Controls:LabelForPoint ShowUnits="False" Point="{Binding}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
私は別の解決策を探しています:(
Alternation Countを使用する場合、AlternationCount
はAlternationCount
であるため、DependencyProperty
プロパティをバインドしているコレクションのアイテムの現在の数にバインドすることもできることに注意してください。
AlternationCount="{Binding Path=OpeningTimes.Count,FallbackValue='100'}"
それが役に立てば幸い。
はい、そうです! ItemsControl
は ItemContainerGenerator プロパティを公開します。 ItemContainerGenerator
には、特定のアイテムのインデックスを見つけるために使用できるIndexFromContainer
などのメソッドがあります。 ItemsControl
をオブジェクトのコレクションにバインドすると、コンテナがそれぞれに自動的に生成されることに注意してください。 ContainerFromItem
メソッドを使用して、バインドされた各アイテムのコンテナを見つけることができます。
より信頼性の高い方法は、値コンバーターを使用して、インデックスを持つ新しいコレクションを生成することです。ヘルパーが2人いると、これはかなり苦痛がありません。 ReactiveUI'sIEnumerable<T>.CreateDerivedCollection()
と、Indexedと呼ばれる他の目的のために作成したヘルパークラスを使用します。
public struct Indexed<T>
{
public int Index { get; private set; }
public T Value { get; private set; }
public Indexed(int index, T value) : this()
{
Index = index;
Value = value;
}
public override string ToString()
{
return "(Indexed: " + Index + ", " + Value.ToString () + " )";
}
}
public class Indexed
{
public static Indexed<T> Create<T>(int indexed, T value)
{
return new Indexed<T>(indexed, value);
}
}
とコンバーター
public class IndexedConverter : IValueConverter
{
public object Convert
( object value
, Type targetType
, object parameter
, CultureInfo culture
)
{
IEnumerable t = value as IEnumerable;
if ( t == null )
{
return null;
}
IEnumerable<object> e = t.Cast<object>();
int i = 0;
return e.CreateDerivedCollection<object, Indexed<object>>
(o => Indexed.Create(i++, o));
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
}
xAMLでは私ができること
<DataGrid
VirtualizingPanel.VirtualizationMode="Recycling"
ItemsSource="{Binding
MoineauPumpFlanks.Stator.Flank.Boundary,
Mode=OneWay,
Converter={StaticResource indexedConverter}}"
AutoGenerateColumns="False"
HorizontalScrollBarVisibility="Hidden"
>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Id">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<!-- Get the index of Indexed<T> -->
<TextBlock
Margin="0,0,5,0"
TextAlignment="Right"
Text="{Binding Path=Index}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Point" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<!-- Get the value of Indexed<T> -->
<TextBlock Content="{Binding Value}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>