How to programatically select an item in a data bound ListBox control

只愿长相守 提交于 2019-12-23 22:22:05

问题


I have a custom styled 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>

and

<ListBox x:Name="LayoutsList" ItemContainerStyle="{StaticResource LayoutsListItemStyle}" ItemsSource="{Binding}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <toolkit:WrapPanel Orientation="Horizontal" MaxWidth="410" />
         </ItemsPanelTemplate>
     </ListBox.ItemsPanel>
 </ListBox>

which displays a border over the selected listbox item (when selected manually). I would like the items in the listbox to act like radio buttons and the first item in the listbox to be selected by default.

I'm trying to set the SelectedIndex of the listbox like this:

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

but it doesn't seem to be doing anything.

How can I programatically select the first (or any other) item in a data bound ListBox?

EDIT

It turns out that SelectedIndex actually works and I can control it and pull the data out of the ListBox as I wish.

So I guess the question would be:

How to I trigger VisualState change on the listbox item programatically?


回答1:


I've managed to achieve this by hooking up to LayoutUpdated event on the ListBox control

<ListBox x:Name="LayoutsList" ItemContainerStyle="{StaticResource LayoutsListItemStyle}" ItemsSource="{Binding}" LayoutUpdated="LayoutsList_LayoutUpdated">

and the 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);

    }
}

Seems a little bit like a brute-force to me but it works and it will keep looping until it can find the element it needs.

Hope that helps someone




回答2:


In WPF you should never get or set the SelectedIndex manually. Instead, set the current item of the ListCollectionView which is bound to the control. The selected index is bound to the current item of the collection view.



来源:https://stackoverflow.com/questions/8696443/how-to-programatically-select-an-item-in-a-data-bound-listbox-control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!