加载 WPF 时在 ListBox 中设置选定项的样式
Posted
技术标签:
【中文标题】加载 WPF 时在 ListBox 中设置选定项的样式【英文标题】:Style SelectedItem in ListBox upon Load WPF 【发布时间】:2022-01-02 01:38:09 【问题描述】:我有一个ListBox
,例如:
<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
加载应用程序时SelectedThing
可能在ViewModel
中定义,因此我希望对其进行相应的样式设置。
当我打开应用然后点击一个项目时效果很好,但是如何在加载时应用样式?
我试过了:
<Style.Triggers>
<DataTrigger Binding="Binding IsEnabled, RelativeSource=RelativeSource Mode=Self" Value="True">
<Setter Property="Background" Value="Purple" />
</DataTrigger>
</Style.Triggers>
但ListBox
的每个项目都已启用,因此它会在加载时将其应用于每个项目。
编辑:
经过一番调试,我发现在加载时设置SelectedThing
,SelectedItem
仍然是null
。
编辑:
这是ViewModel
中的OnLoaded
方法,如果用户在之前使用该应用程序时选择了它,我将在其中设置SelectedThing
。目的是在关闭和重新打开应用后保留选择。
public IAsyncRelayCommand OnLoadedCommand get; set;
在构造函数中:
OnLoadedCommand = new AsyncRelayCommand(OnLoaded);
在视图中:
<b:Interaction.Triggers>
<b:EventTrigger EventName="Loaded">
<b:InvokeCommandAction Command="Binding OnLoadedCommand" />
</b:EventTrigger>
</b:Interaction.Triggers>
实际方法:
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;
【问题讨论】:
如果您设置了SelectedThing
和SelectedItem
未设置,您的绑定不起作用或者您没有正确实现INotifyPropertyChanged
。根据您发布的代码不可能说。这不是一个可重复的例子。
SelectedItem
在单击 ListBox 中的项目后设置并且行为正确 -> 绑定确实有效。正如我在代码中所示,我也在实现INotifyPropertyChanged
。问题是 SelectedThing
可以在 ViewModel 的 OnLoaded
方法中设置,这样,SelectedItem
没有设置。
是的,如果您提出更改通知,它应该是。同样,您没有显示代码的所有相关部分。为什么以及如何在OnLoaded
中设置视图模型属性?
我已经用更相关的东西更新了代码,谢谢。
selected
真的存在于源集合中吗?
【参考方案1】:
没有选择项目的原因是因为您将SelectedThing
源属性设置为不在ViewModels
源集合中的值。
正如您已经发现的那样,这样效果更好:
var selectedViewModel = ViewModels.Where(x => x.SelectedThing == selected.SelectedThing).FirstOrDefault();
SelectedThing = selectedViewModel;
要选择的项目必须存在于源集合中。
【讨论】:
以上是关于加载 WPF 时在 ListBox 中设置选定项的样式的主要内容,如果未能解决你的问题,请参考以下文章