0

Пытаюсь отобразить данные не в главном окне, но не могу понять, почему они не отображаются. Есть класс:

public class StudentModel : INotifyPropertyChanged
{

public StudentModel(int remoteId, int receiverId) { RemoteId = (ushort)remoteId; ReceiverId = receiverId; } public StudentModel() {

}

public List<string> textString { get; set; } = new List<string>();

protected virtual void RaisePropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }

public void QuestionsAdd(string text) { Questions.Add($"{Questions.Count + 1}. " + $" {text}"); } }

В другом классе я добавляю в коллекцию объекты:

public class MainWindowViewModel
    {
        public ObservableCollection<StudentModel> Students { get; set; } = new ObservableCollection<StudentModel>();
    IFileService _fileService;

    IDialogService _dialogService;

    private readonly DeviceManager deviceManager = new DeviceManager(new VotumDevicesManager());

    public MainWindowViewModel() { }
    public MainWindowViewModel(IDialogService dialogService, IFileService fileService)
    {
        _dialogService = dialogService;
        _fileService = fileService;

        for (int i = 0; i &lt; 32; i++)
        {
            Students.Add(new StudentModel());
        }

        deviceManager.votumManager.ButtonClicked += VotumManager_ButtonClicked;
    }

private void GettingAQuestionsRemotely(int RemoteId, ButtonClickEventArgs e) { if (e.IsT2TextPresent && e.Button.Type == ButtonType.PauseT2) { App.Current.Dispatcher.Invoke(new Action(() => { //Добавляем в коллекцию объекты Students.FirstOrDefault(x => x.RemoteId.Equals(Convert.ToUInt16(RemoteId)))?.QuestionsAdd(e.T2Text); var std = Students.FirstOrDefault(x => x.RemoteId.Equals(Convert.ToUInt16(RemoteId))); if (std != null) { std.Question = e.T2Text; OnTick -= std.UpTime; } })); } }

public RelayCommand<StudentModel> questionCmd = null; public RelayCommand<StudentModel> QuestionCmd => questionCmd ?? (questionCmd = new RelayCommand<StudentModel>((param) => { new QuestionView().ShowDialog(); }, (param) => { return (param != null && param.Questions.Count == 0) ? false : true; } )); }

XAML:

<Window x:Class="Guess.Yourself.QuestionView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Guess.Yourself"
        mc:Ignorable="d"
        Title="Архив вопросов" 
        SizeToContent="WidthAndHeight"
        Topmost="True"
        ResizeMode="NoResize"
        WindowStartupLocation="CenterScreen">
    <Window.DataContext>
        <local:StudentModel/>
    </Window.DataContext>
    <Grid>
        <ListView x:Name="lv" Background="Gray" Height="300" MaxHeight="300" MinWidth="250" ItemsSource="{Binding Questions}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}" FontSize="32" Foreground="White"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Window>
Genas
  • 153
  • Потому что вы создаете новый экземпляр прямо в разметке. Это неправильно. Убирайте Window.DataContext из разметки – Андрей NOP Jun 23 '20 at 09:54
  • @АндрейNOP Хорошо, а как тогда корректно сделать? В ListView так же не правильно же... – Genas Jun 23 '20 at 09:57
  • Нет, новый экземпляр не должен тут создаваться вообще, кто-то должен установить готовый экземпляр извне – Андрей NOP Jun 23 '20 at 10:00
  • @АндрейNOP В классе MainWindowViewModel я создаю объект класса StudentModel и там же в методе GettingAQuestionsRemotely добавляю текст лист. – Genas Jun 23 '20 at 10:09
  • Хорошо, а как вы устанавливаете DataContext вашему окну QuestionView? – Андрей NOP Jun 23 '20 at 10:17
  • @АндрейNOP Получается, что никак. В этом и загвоздка. Раньше я просто передавал в команде список объектов через параметр команды, в code-behinde QuestionView устанавливал ItemSource получая список через конструктор. Так работало, но если в главном окне менялась размерность списка, то при скролле списка объектов в окне QuestionView ловил эксепшн об изменении списка в другом окне. – Genas Jun 23 '20 at 10:30
  • А как вы окно создаете? – Андрей NOP Jun 23 '20 at 10:33
  • @АндрейNOP Не совсем понял вопроса. Если Вы про вторичное окно, то самым обычным образом public QuestionView() => InitializeComponent(); Точно так же и первое создаю. – Genas Jun 23 '20 at 10:40
  • Кто и где дергает этот конструктор? Почему этот кто-то не устанавливает окну нужный DataContext? – Андрей NOP Jun 23 '20 at 10:43
  • @АндрейNOP У главного окна DataContext - DataContext = new MainWindowViewModel(new DefaultDialogService(), new TextFileService()); У второго окна контекста на данный момент нет, конструктор дёргается в одном месте, в классе MainWindowViewModel в команде открытия окна new QuestionView().ShowDialog(); – Genas Jun 23 '20 at 10:52
  • Ну вот здесь значит и надо установить DataContext: new QuestionView { DataContext = ... }.ShowDialog(); – Андрей NOP Jun 23 '20 at 11:06
  • Другой вопрос — на сколько это правильно, VM по хорошему не должна зависеть от View, на перспективу вам добавить прослойку, которая будет создавать нужную View по запросу от VM – Андрей NOP Jun 23 '20 at 11:08
  • @Андрей NOP Действительно получилось!) Спасибо!) Оформите ответ, пусть Вам зачтётся!) – Genas Jun 23 '20 at 12:18
  • Напишите самостоятельно, у меня нет желания. Да и никакие дополнительные очки мне уже не нужны :) – Андрей NOP Jun 23 '20 at 12:29

1 Answers1

0

В общем и целом дело заключалось в том, что не нужно было DataContext устанавливать в XAML, а установить в коде там, где окно создаётся:

public RelayCommand<StudentModel> QuestionCmd => questionCmd ?? (questionCmd = new RelayCommand<StudentModel>((param) =>
        {
            new QuestionView() { DataContext = param }.ShowDialog();
        },
            (param) =>
            {
                return (param != null && param.Questions.Count == 0) ? false : true;
            }
            ));
Genas
  • 153