@Ignatiy2

Почему из SelectedItem Listbox я получаю предыдущий выбранный элемент?

У меня есть listbox:
<ListBox ItemsSource="{Binding Notes}" 
                         HorizontalContentAlignment="Stretch" 
                         VerticalContentAlignment="Stretch"
                         Name="NoteList"
                         SelectedItem="{Binding SelectedNote}"
                         >
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" Background="#FFD7B4F3" >
                                <TextBlock Text="{Binding Title}" FontSize="15" Margin="2"/>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="GotFocus">
                            <i:InvokeCommandAction Command="{Binding ActivatePanelCommand}" CommandParameter="{Binding SelectedNote}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </ListBox>


Код ViewModel:
class MainVM : INotifyPropertyChanged
    {
        static public ApplicationContext DB { get; private set; }
        IEnumerable<Note> notes;
        Note selectedNote;

        public IEnumerable<Note> Notes
        {
            get { return notes; }
            set
            {
                notes = value;
                OnPropertyChanged();
            }
        }

        public Note SelectedNote
        {
            get { return selectedNote; }
            set
            {
                selectedNote = value;
                OnPropertyChanged();
            }
        }
        
        public RelayCommand ActivatePanelCommand
        {
            get
            {
                return activatePanelCommand ??
                    (activatePanelCommand = new RelayCommand((selectedItem) =>
                    {
                        Note note = selectedItem as Note;
                        if(note != null)
                        {
                            MessageBox.Show(note.Title);
                        }
                    }));
            }

        public MainVM()
        {
            CurrentContentVM = new WriteNoteVM();
            DB = new ApplicationContext();
            DB.Notes.Load();
            Notes = DB.Notes.Local.ToBindingList();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName]string prop = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));

        }
    }


Проблема в том, что из SelectedNote я получаю предыдущий выбранный элемент(а при первом клике ничего не выводится, так как SelectedNote изначально null). Что делать?
  • Вопрос задан
  • 307 просмотров
Решения вопроса 2
SpacePurr
@SpacePurr
c#, wpf
Я не эксперт, но возможно событие GotFocus срабатывает раньше, чем присваивается значение выделенному элементу SelectedItem.

Решить можно так.

Помимо библиотеки interactivity подключите библиотеку interactions:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei ="http://schemas.microsoft.com/expression/2010/interactions"


Подключение события будет выглядеть вот так:
<i:Interaction.Triggers>
    <i:EventTrigger EventName="GotFocus">
        <ei:CallMethodAction MethodName="NoteList_GotFocus"
                             TargetObject="{Binding }"/>
    </i:EventTrigger>
</i:Interaction.Triggers>


ViewModel:
public void NoteList_GotFocus(object sender, RoutedEventArgs e)
{
    if (e.OriginalSource is ListBoxItem lvi)
    {
        Note note = lvi.DataContext as Note;
        MessageBox.Show(note.Title);
    }
}


Доказательство:
5dfc71a903242851876417.gif
Ответ написан
Комментировать
AlexanderYudakov
@AlexanderYudakov
C#, 1С, Android, TypeScript
Возможно, GotFocus срабатывает быстрее SelectionChanged.

Чтобы дождаться корректной обработки обоих событий, фрагмент:
Note note = selectedItem as Note;
if(note != null)
{
    MessageBox.Show(note.Title);
}

имеет смысл завернуть в Dispatcher.BeginInvoke().
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы