一、ListBox中為什麼選擇同一項不能每次都觸發SelectionChanged事件呢?
當我需要每次點選ListBox的選中項,都觸發事件。找到最符合的事件為SelectionChanged事件。但使用SelectionChanged事件時,並不能每次都觸發。
這是因為SelectionChanged事件是選中項發生變化時才會觸發,如果上次選中與本次相同,則單擊是不會觸發SelectionChanged事件。
二、使用附加屬性宣告 ICommand
我們可以使用附加屬性宣告一個ICommand解決以上問題。具體步驟如下:
(1)宣告一個附加屬性。
class AttachedLib
{
public static ICommand GetClick(DependencyObject obj)
{
return (ICommand)obj.GetValue(ClickProperty);
}
public static void SetClick(DependencyObject obj, ICommand value)
{
obj.SetValue(ClickProperty, value);
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ClickProperty =
DependencyProperty.RegisterAttached("Click", typeof(ICommand), typeof(AttachedLib), new PropertyMetadata(null));
}
(2)將該附加屬性新增到ListBox上,並繫結待實現的ICommand。
<Grid>
<ListBox Margin="10"
ItemsSource="{Binding StudentCollection}"
ItemTemplate="{StaticResource StudentTemplate}"
local:AttachedLib.Click="{Binding SelectCommand}"></ListBox>
</Grid>
public ICommand SelectCommand { get; set; }
private void ExecuteSelectCommand(object obj)
{
if (obj is Student student)
{
MessageBox.Show($"{student.Id},{student.Name},{student.Age}","選中的學生資訊");
}
}
public MainWindowVM()
{
StudentCollection = new ObservableCollection<Student>()
{
new Student(){Id = 1,Name = "Dwayne", Age = 10,},
new Student(){Id = 2,Name = "John", Age = 11,},
new Student(){Id = 3,Name = "Aaron", Age = 12,},
};
SelectCommand=new RelayCommand(ExecuteSelectCommand);
}
(3)在ListBox的ListBoxItem模板中,新增一個Button,Button的Command使用相對路徑繫結該附加屬性。
<DataTemplate x:Key="StudentTemplate" DataType="{x:Type local:Student}">
<Button BorderThickness="0"
Background="Transparent"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}, Path=(local:AttachedLib.Click)}"
CommandParameter="{Binding}">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="10,5" Width="100" Text="{Binding Id}"></TextBlock>
<TextBlock Margin="10,5" Width="200" Text="{Binding Name}"></TextBlock>
<TextBlock Margin="10,5" Width="100" Text="{Binding Age}"></TextBlock>
</StackPanel>
</Button>
</DataTemplate>
三、總結
通過以上操作,由Button觸發單擊事件,就可以實現”每次點選ListBox的選中項,都觸發事件“的預期目標。