Silverlight получить ListBoxItem из связанного списка - PullRequest
1 голос
/ 13 октября 2010

У меня есть ListBox в файле с именем Downloads.XAML. Элементы, связанные с этим ListBox, взяты из связанного списка в моей ViewModel. У меня есть состояния, которые определены в стиле ListBoxItem в другом элементе управления XAML, которые должны быть запущены в зависимости от набора свойств связанного элемента. У меня проблема в том, что я не могу получить ListBoxItem из ListBox, так как .SelectedItem ссылается на фактический связанный объект, а не ListBox. Я попытался использовать ListBox.ItemContainerGenerator, но это возвращает ListItem только в 80% случаев, остальные 20% времени это возвращает ноль, и поэтому VisualState не устанавливается в соответствующем ListBoxItem.

Я также пытался установить состояния через триггеры данных в XAML, но опять же, это не работает 100% времени. Кто-нибудь знает, как я могу легко получить ListBoxItem из связанного объекта, чтобы запустить VisualState на нем, что мне нужно?

Элементы, привязанные к списку в ListBox, добавляются с другой страницы - страница загрузок не видна в настоящее время, и я думаю, что именно поэтому ListBoxItems не найдены или почему не запускаются состояния

Вот XAML шаблона элемента управления ListBoxItem в стиле:

  <Style x:Key="PrimaryDownloadsListBoxItemStyle" TargetType="ListBoxItem">
    <Setter Property="Padding" Value="3"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="VerticalContentAlignment" Value="Top"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="TabNavigation" Value="Local"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem" >
                <Grid Margin="0" Height="71">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="5"/>
                        <RowDefinition Height="5"/>
                        <RowDefinition Height="52"/>
                        <RowDefinition Height="5"/>
                        <RowDefinition Height="5"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="5"/>
                        <ColumnDefinition Width="90"/>
                        <ColumnDefinition Width="10"/>
                        <ColumnDefinition Width="10"/>
                        <ColumnDefinition Width="184"/>
                        <ColumnDefinition Width="116"/>
                        <ColumnDefinition Width="220"/>
                        <ColumnDefinition Width="67"/>
                        <ColumnDefinition Width="10"/>
                    </Grid.ColumnDefinitions>                        
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver"/>
                            <VisualState x:Name="Disabled"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected"/>
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <ColorAnimation Duration="0" To="#FF191919" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="fillColor2" d:IsOptimized="True"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="SelectedUnfocused"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused"/>
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="LayoutStates">
                            <VisualState x:Name="AfterLoaded"/>
                            <VisualState x:Name="BeforeLoaded"/>
                            <VisualState x:Name="BeforeUnloaded"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="DownloadStates">
                            <VisualState x:Name="DownloadInProgress">
...

Вот код, который я использую в коде, чтобы попытаться установить состояние:

        private void SetDownloadState(object[] itemDetails)
    {
        DispatcherHelper.CheckBeginInvokeOnUI(() =>
                                   {
                                       var item = itemDetails;
                                       if (item != null)
                                       {
                                           string state = (string)item[0];
                                           VideoItem vi = (VideoItem)item[1];

                                           if (DownloadsListBox.ItemContainerGenerator != null)
                                           {
                                               DownloadsListBox.ScrollIntoView(DownloadsListBox.Items[0]);

                                               foreach (var videoitem in
                                                   DownloadsListBox.Items.Where(videoitem => videoitem == vi))
                                               {
                                                   DownloadsListBox.ScrollIntoView(videoitem);
                                               }

                                               var listBoxItem = DownloadsListBox.ItemContainerGenerator.ContainerFromItem(vi) as ListBoxItem;

                                               //show the status state on this item.
                                               if (listBoxItem != null)
                                               {
                                                   if (state.ToUpper() == "DOWNLOADING")
                                                   {
                                                       bool success = VisualStateManager.GoToState(listBoxItem, "DownloadInProgress", true);
                                                       if (!success)
                                                       {
                                                           Debug.WriteLine("Error changing state in DownloadsView to Downloading!");
                                                       }
                                                   }
                                                   else if (state.ToUpper() == "COMPLETED")
                                                   {
                                                       bool success = VisualStateManager.GoToState(listBoxItem, "DownloadComplete",
                                                                                    true);
                                                       if (!success)
                                                       {
                                                           Debug.WriteLine("Error changing state in DownloadsView to completed!");
                                                       }
                                                   }
                                               }
                                               else
                                               {
                                                   Debug.WriteLine("listBoxItem is null");
                                               }
                                           }
                                       }
                                   });
    }

Я пытался добавить триггеры в ContentTemplate в стиле, но он не работал 100% времени:

                        <i:Interaction.Triggers>
                        <ei:DataTrigger Binding="{Binding DownloadState}" Value="Downloading">
                            <ei:GoToStateAction StateName="Focused"/>
                            <ei:GoToStateAction StateName="DownloadInProgress"/>
                        </ei:DataTrigger>
                        <ei:DataTrigger Binding="{Binding DownloadState}" Value="DownloadComplete">
                            <ei:GoToStateAction StateName="Focused"/>
                            <ei:GoToStateAction StateName="DownloadComplete"/>
                        </ei:DataTrigger>
                    </i:Interaction.Triggers>

1 Ответ

1 голос
/ 19 октября 2010

Мне удалось получить ListBoxItem, установив свойство в моей модели представления для templatedParent сетки в ContentTemplate, которая затем ссылалась на listboxitem:

"{Binding RelativeSource={RelativeSource TemplatedParent}}"

Надеюсь, это когда-нибудь кому-нибудь поможет:)

...