I have a ListBox
, as such:
<ListBox
//other stuff
ItemsSource="{Binding ViewModels, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedThing, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Purple" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
ViewModel.cs:
public SomeType SelectedThing
{
get => selectedThing;
set => //set with INotifyPropertyChanged
}
public ObservableCollection<SomeType> ViewModels
{
get => viewModels;
set => //set with INotifyPropertyChanged
}
It's possible that SelectedThing
is defined in the ViewModel
when loading the app, so I want it to be styled accordingly.
It works great when I open the app and then click on an item, but how can the style be applied on load?
I tried with:
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="True">
<Setter Property="Background" Value="Purple" />
</DataTrigger>
</Style.Triggers>
But every item of the ListBox
is enabled, so it applies it to every item upon load.
EDIT:
After debugging a bit, I found out that when setting SelectedThing
on load, SelectedItem
remains null
.
EDIT:
Here is the OnLoaded
method in the ViewModel
, where I am setting SelectedThing
if the user has selected it while previously using the app. The purpose is to keep the selection after closing and reopening the app.
public IAsyncRelayCommand onl oadedCommand { get; set; }
In the constructor:
OnLoadedCommand = new AsyncRelayCommand(OnLoaded);
In the View:
<b:Interaction.Triggers>
<b:EventTrigger EventName="Loaded">
<b:InvokeCommandAction Command="{Binding onl oadedCommand}" />
</b:EventTrigger>
</b:Interaction.Triggers>
The actual method:
public async Task OnLoaded()
{
//other stuff
if (App.Current.Properties.Contains(nameof(SelectedThing)))
{
var selected = JsonConvert.DeserializeObject<SomeType>(App.Current.Properties[nameof(SelectedThing)].ToString());
SelectedThing = selected;
}
}
CodePudding user response:
The reason why there is no item selected is because you are setting the SelectedThing
source property to a value that's not in the ViewModels
source collection.
As you have already discovered, this works better:
var selectedViewModel = ViewModels.Where(x => x.SelectedThing == selected.SelectedThing).FirstOrDefault();
SelectedThing = selectedViewModel;
The item to be selected must be present in the source collection.