1

Доброго времени суток, дорогие знатоки. Разрабатываю WPF app (EntityFramework, Sqlite, MMVM). Такой вопрос возник у меня:

Есть обычная ViewModel:

public class MainWindowViewModel : ViewModelBase
{
    private MyDbContext context = new MyDbContext(); //контекст
    public ObservableCollection<Record> Records { get; set; }

    public MainWindowViewModel()
    {     
        Records = new ObservableCollection<Record>(context.Records.ToList());
    }
}

В MainWindow.xaml добавляю так:

<Window.DataContext>
    <ViewModels:MainWindowViewModel/>
</Window.DataContext>

...иии после волшебных манипуляций XAMLдизайнера, я получаю:

Ошибка

а также: зависший секунд на 10 Visual Studio, предупреждение о том, что сведения о задержке отправлены в Майкрософт и т.д. И так каждый раз когда я переключаюсь с кода в XAML редактор.

Хотя после запуска приложения все отлично с binding's, все отлично работает. Есть вариант перенести все в code-behind и делать: DataContext = new ViewModel(), но данный способ не подходит с религиозных причин. Спасибо за внимание.

UPDATE: Дизайнер ругается на эту строчку: Records = new ObservableCollection<Record>(context.Records.ToList()); Он почему-то не может получить доступ к данным контекста. Как его перехитрить?

  • с connectionString все отлично. – Volodymyr Rets Jun 12 '17 at 19:08
  • 2
    Советую задавать DataContext на code-behind. А еще лучше - используйте Dependency Injection. – MihailPw Jun 12 '17 at 19:15
  • @AGS17 не лучшая идея задавать DataContext в code-behind. – sp7 Jun 12 '17 at 20:11
  • @sp7 вообще плохая идея это делать собственноручно. Но если выбирать между заданием на вьюхе и заданием на code-behind - второй вариант выглядит куда логичней. – MihailPw Jun 12 '17 at 21:03
  • 1
    Вы делаете неправильно. EF-entity — это модель, а не VM. И работать с ними в UI-потоке категорически воспрещено, если вы, конечно, не хотите, чтобы ваше приложение висло время ото времени. – VladD Jun 12 '17 at 21:23
  • 1
    @AresGod, а вам очень сильно нужны данные из БД во время разработки? Если нет, посмотрите этот топик: https://ru.stackoverflow.com/questions/678612/intellisense-для-viewmodel-в-редакторе-xaml-visual-studio а DataContext устанавливайте в другом месте – Андрей NOP Jun 13 '17 at 07:35
  • @Андрей, спасибо, полезно. Но хотелось все-таки решить свою проблему с IsDesignTimeCreatable, которое не работает. – Volodymyr Rets Jun 13 '17 at 16:44
  • @VladD, т.е. нужно грузить данные асинхронно от UI? Во ViewModel await-ить? Все CRUD действия делать используя асинхронные команды? – Volodymyr Rets Jun 13 '17 at 16:45
  • @AresGod: Ну, это было бы вообще идеальным решением, да. – VladD Jun 13 '17 at 20:20
  • @VladD, спасибо, это уже реализовал. Только не понял как мне асинхронно присвоить свойству obserable collection. Пока что сделал так: private async Task LoadData(object param) { await Task.Run(() => { Records.Clear(); foreach(var item in Context.Records) { Records.Add(item); } } }

    Хотелось бы что-то на подобии: await Task.Run(()=>Records = new ObservableCollection<Record>(context.Records); }

    – Volodymyr Rets Jun 13 '17 at 21:09
  • @AresGod: Вам нужно асинхронно получить модельные данные (то есть, сделать запрос к базе), и затем в UI-потоке создать на них VM-обёртки (не к модельным же данным биндиться?) Если данных реально много (по идее, это уже не очень, т. к. юзер вряд ли сможет прочитать и понять миллион строк), то лучше сделать либо объекты иммутабельными, либо грузить лениво, по частям и только по запросу. – VladD Jun 13 '17 at 21:24
  • @VladD, у меня не большой проект. Записей порядка несколько десятков тысяч. Лениво и так грузиться все. Мне главное сделать все операции без фриза UI, с остальным проблем не будет) А так, спасибо за информацию – Volodymyr Rets Jun 13 '17 at 21:36
  • 1
    @AresGod: Кстати, по поводу установки DataContext в XAML'е: https://ru.stackoverflow.com/a/562586/10105, https://ru.stackoverflow.com/q/520245/10105 (хотя вопрос, конечно, религиозный). – VladD Jun 13 '17 at 21:54

1 Answers1

2

РЕШЕНИЕ: Сделал временно все в Code-behind, а для включения подсказок в IntelliSence использую: d:DataContext="{d:DesignInstance Type=ViewModels:MainWindowViewModel}" Подробнее: IntelliSense для ViewModel в редакторе XAML Visual Studio