[英]How to programatically select an item in a data bound ListBox control
我有一个自定义样式的ListBox:
<phone:PhoneApplicationPage.Resources>
<Style x:Key="LayoutsListItemStyle" TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid Height="170" Width="170" Margin="0,0,20,20">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="LayoutStates">
<VisualState x:Name="BeforeUnloaded"/>
<VisualState x:Name="BeforeLoaded"/>
<VisualState x:Name="AfterLoaded"/>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="border">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Thickness>4</Thickness>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="SelectedUnfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="border" Width="170" Height="170" BorderBrush="{StaticResource PhoneAccentBrush}">
<Grid>
<Image Source="{Binding ThumbnailPath}" Width="170" Height="170" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Resources>
和
<ListBox x:Name="LayoutsList" ItemContainerStyle="{StaticResource LayoutsListItemStyle}" ItemsSource="{Binding}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" MaxWidth="410" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
它会在所选列表框项目上方显示边框(手动选择时)。 我希望列表框中的项目像单选按钮一样工作,并且列表框中的第一个项目默认为选中状态。
我试图像这样设置列表框的SelectedIndex:
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
// Loads a list of available Layouts to a ListBox
XDocument layoutSummary = XDocument.Load("Content/LayoutSummary.xml");
var layouts =
from elem in layoutSummary.Descendants("ComicLayout")
select new ComicLayout
{
Name = (string)elem.Attribute("Name").Value,
FriendlyName = (string)elem.Attribute("FriendlyName").Value,
ThumbnailPath = "Content/LayoutIcons/" + (string)elem.Attribute("Name").Value + ".png"
};
LayoutsList.DataContext = layouts;
LayoutsList.SelectedIndex = 1;
}
但它似乎没有任何作用。
如何以编程方式选择数据绑定ListBox中的第一个(或任何其他)项目?
编辑
事实证明,SelectedIndex实际上有效,我可以对其进行控制,并根据需要将数据拉出ListBox。
所以我想问题是:
如何以编程方式触发列表框项上的VisualState更改?
我设法通过挂接到ListBox控件上的LayoutUpdated事件来实现此目的
<ListBox x:Name="LayoutsList" ItemContainerStyle="{StaticResource LayoutsListItemStyle}" ItemsSource="{Binding}" LayoutUpdated="LayoutsList_LayoutUpdated">
和LayoutsList_LayoutUpdated()
:
private void LayoutsList_LayoutUpdated(object sender, EventArgs e)
{
if ((ListBoxItem)LayoutsList.ItemContainerGenerator.ContainerFromIndex(LayoutsList.SelectedIndex) != null)
{
ListBoxItem selectedItem = (ListBoxItem)LayoutsList.ItemContainerGenerator.ContainerFromIndex(LayoutsList.SelectedIndex);
VisualStateManager.GoToState(selectedItem, "Selected", true);
}
}
在我看来,这有点像蛮力,但它仍然有效,并且会一直循环播放,直到找到所需的元素为止。
希望可以帮助某人
在WPF中,永远不要手动获取或设置SelectedIndex
。 而是,设置绑定到控件的ListCollectionView
的当前项。 所选索引绑定到集合视图的当前项目。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.