我希望能够访问另一个ListBox
内的ListBox
的索引并增加该索引。我尝试使用ItemContainerGenerator
但是当我将项目转换为ListBox
或ItemsControl
时,它会返回null
。
我想在后面的代码或视图模型中增加索引。
这是我模板的基本结构
<Window x:Class="WpfApplication12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="MyListStyle" TargetType="{x:Type ListBox}">
<Setter Property="BorderThickness" Value="0"></Setter>
<Setter Property="SelectedIndex" Value="0"></Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal">
</VirtualizingStackPanel>
</ItemsPanelTemplate >
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Visibility" Value="Collapsed"></Setter>
<!--<Setter Property="Margin" Value="2" />-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ListBox Name="InnerList" ItemsSource="{Binding}" ></ListBox>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Visibility" Value="Visible"/>
</Trigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="1" Click="Button_Click">button</Button>
<ListBox Style="{StaticResource MyListStyle}" Name="ListItemsControl" VirtualizingPanel.IsVirtualizing="True" Grid.Row="0"></ListBox>
</Grid>
</Window>
Here is some code to load the list
public MainWindow()
{
InitializeComponent();
CompositeCollection cc = new CompositeCollection();
cc.Add(new List<int>() { 1, 2, 3, 4, 5 });
cc.Add(new List<int>() { 6, 7, 8, 9, 10 });
cc.Add(new List<int>() { 11, 12, 13, 14, 15 });
ListItemsControl.ItemsSource = cc;
}
答案 0 :(得分:1)
我建议您使用断点并浏览可视化工具(如果您想要一个变量,请使用小放大镜图标),这样您就可以了解此代码的工作原理。
将其放入按钮事件处理程序:
private void Button_Click(object sender, RoutedEventArgs e)
{
//var item = ListItemsControl.ItemContainerGenerator.ContainerFromIndex(1) as ListBoxItem;
//var innerListBox = VisualTreeHelper.GetChild(item, 0) as ListBox;
//innerListBox.SelectedIndex++;
// For every item in the ListItemsControl
for (int i = 0; i < ListItemsControl.Items.Count; i++)
{
// Get the item container for the specified index and cast it as ListBoxItem.
var item = ListItemsControl.ItemContainerGenerator.ContainerFromIndex(i)
as ListBoxItem;
// Then, get the first child of the ListBoxItem and cast it as a ListBox.
// Note that I'm making an assumption that it'll always be a ListBox,
// which is why you should perform some checks in a production case,
// to avoid exceptions.
var innerListBox = VisualTreeHelper.GetChild(item, 0) as ListBox;
// Lastly, I increment the index of this ListBox.
innerListBox.SelectedIndex++;
}
}
注释掉是改变一个元素的索引的方法。在下面,我正在递增所有三个内部列表框的索引。这让你知道如何到达它们,所以从那里你可以根据自己的喜好改变它。显然,您可能希望添加代码以检查null
并在尝试增加SelectedIndex
属性之前确认正确的类型,但这并不是很困难。
旧答案(基于第一篇文章):
这是一个代码隐藏的示例。如果您想要MVVM
,请告诉我。您也可以使用Binding
到SelectedIndex
属性,但是您必须确保已INotifyPropertyChanged
已实施。
<强> XAML 强>:
<Window x:Class="LB.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="219.965" Width="217.535">
<StackPanel>
<ListBox x:Name="lbOuter" HorizontalContentAlignment="Stretch">
<ListBox.Items>
<TextBlock>Outer Item #1</TextBlock>
<TextBlock>Outer Item #1</TextBlock>
<ListBox x:Name="lbInner" BorderBrush="Black" BorderThickness="1" Margin="5">
<ListBox.Items>
<TextBlock>Inner Item #1</TextBlock>
<TextBlock>Inner Item #2</TextBlock>
<TextBlock>Inner Item #3</TextBlock>
</ListBox.Items>
</ListBox>
<TextBlock>Outer Item #3</TextBlock>
<TextBlock>Outer Item #4</TextBlock>
</ListBox.Items>
</ListBox>
<StackPanel Orientation="Horizontal">
<Button Content="Increment Outer" Margin="5" Click="Button_Click"/>
<Button Content="Increment Inner" Margin="5" Click="Button_Click_1"/>
</StackPanel>
</StackPanel>
</Window>
<强>代码隐藏强>:
using System.Windows;
namespace LB
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (lbOuter.SelectedIndex < (lbOuter.Items.Count - 1))
{
lbOuter.SelectedIndex++;
}
else
{
lbOuter.SelectedIndex = 0;
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
if (lbInner.SelectedIndex < (lbInner.Items.Count - 1))
{
lbInner.SelectedIndex++;
}
else
{
lbInner.SelectedIndex = 0;
}
}
}
}
上面的代码实际上会循环你的选择。所以,如果你到达目的地,那么你需要索引0.你可以删除它,如果你不想要那个功能。