У меня есть 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>