0

Есть задача, написать диспетчер задач на с# с патерном mvvm. У меня возникла проблема с привязкой. Фишка в том что если я напрямую бинжу к Process.GetProcesses() через ObjectDataProvider то список процессов не обновляется. Проблема в обновлении именно. Подскажите,как его привязать правильно? Еще интересно, как его можно отсортировать? Ну, список. Не нарушая mvvm.

Kromster
  • 13,809
  • А почему он должен обновляться? Вы получили данные, сбиндили их на UI, и ожидаете, что они сами обновятся? Почему? – Anton Shakalo May 29 '18 at 11:04
  • Касательно отрисовки - насколько я понял вы используете ListBox, хорошем решением будет определить для него ItemTemplate. Первое - это просто самое удобное решение, второе - оно нисколько не противоречит MVVM. Что такое DataTemplate и как с ним работать можно ознакомиться тут и тут. –  May 29 '18 at 12:37
  • Я понимаю что они обновляться не будут, но а вдруг) думал если к методу привяжу норм будет, вроде где-то даже работало.. – opadfnezig May 30 '18 at 06:19

2 Answers2

0

Рабочим решением будет использовать Dispatcher Timer

Пример:

 public class ViewModel : INotifyPropertyChanged
 {
     private DispatcherTimer changeTimer;

       ViewModel ()
      { 
       changeTimer = new DispatcherTimer...
       changeTimer.Tick += Tick;
       changeTimer.Interval = TimeSpan.FromSeconds(1);
  }

  private ObservableCollection<Model> items;
  public ObservableCollection<Model> Items 
  {
    get  
    {
        return items;
    }
    set
    {
        if(value != items)
        {
          items = value;
          NotifyPropertyChanged("Items"); 
          changeTimer.Start();
        }
    }
  }

 private void LoadData()
 {
     Items = // здесь загружаем данные
  }
  private Tick(...)
  {
     LoadData();
  }

 }
0

пример работы

Если вы планируете через свою программу убивать процессы, то вам нужно использовать не List<string> как у меня, а ObservableCollection<string> и еще добавить свойство для SelectedItem.

public class MainViewModel : INotifyPropertyChanged, IDisposable
{
    public event PropertyChangedEventHandler PropertyChanged;


    private Timer _timer;

    //ctor
    public MainViewModel()
    {
        LoadProcesses();
        RunTimer();
    }

    private List<string> _Processes = new List<string>();
    public List<string> Processes
    {
        get => _Processes;
        set
        {
            _Processes = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Processes)));
        }
    }


    private void RunTimer()
    {
        _timer = new Timer();
        _timer.Interval = 2000;
        _timer.Elapsed += _timer_Elapsed;
        _timer.Start();

    }

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        LoadProcesses();
    }

    private void LoadProcesses()
    {
        var ps = Process.GetProcesses()
                        .Select(p => p.ProcessName)
                        .OrderBy(n => n)
                        .Distinct()
                        .ToList();

        Processes = ps;
    }

    public void Dispose()
    {
        _timer.Stop();
        _timer.Dispose();
    }
}
Bulson
  • 9,411
  • А где потом вызывать Dispose? Создать ивент на закрытие окна и там вызывать или где? – opadfnezig May 30 '18 at 06:37
  • Dispose будет вызван автоматом при закрытии MainViewModel – Bulson May 30 '18 at 07:23