klashagelqvist
klashagelqvist

Reputation: 1261

Wpf Prism event update control

I have a standard Listbox which is bound to a property in my viewmodel

   <ListBox ItemsSource="{Binding StatusList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  Name="myListBox"  BorderThickness="0" HorizontalAlignment="Stretch">        
                </ListBox>

The property

 private ObservableCollection<String> _statusList;
        public ObservableCollection<String> StatusList
        {
            get { return _statusList;}
            set { _statusList = value;}
        }

The view model subscribes to an event

  _eventAggregator.GetEvent<PublishStatusEvent>().Subscribe(this.OnStatusChanged);

which excecutes a function that just adds strings to the collection

 private void OnStatusChanged(string status)
        {
            StatusList.Add(status);
        }

When i exceute a long running task that publishes events , i want the listbox to update. If i debug i can see the events coming but the listbox is not getting updated until the task is finished. The task is inititated in the viewmodel.

Anyone?

Upvotes: 0

Views: 448

Answers (2)

Phil
Phil

Reputation: 43021

I'm guessing that your 'long running task' is actually running on the UI thread and therefore blocking the UI thread even though you're successfully publishing and subscribing events. This would explain why the events all appear when the task completes.

Try moving your task to another thread, maybe something like this:

public class MyViewModel
{
    private readonly IEventAggregator _aggregator;

    public MyViewModel(IEventAggregator aggregator)
    {
        _aggregator = aggregator;
        var tf = new TaskFactory();
        tf.StartNew(SendStatusMessages);
    }

    private void SendStatusMessages()
    {
        for (int i = 0; i < 50; i++)
        {
            Thread.Sleep(1000);

            var s = "item: " + i;
            Debug.WriteLine("Sending" + s);
            _aggregator.GetEvent<StatusEvent>().Publish(s);
        }
    }

You will then need to change your subscription code, as suggested by @shriek, to

_aggregator.GetEvent<PublishStatusEvent>().Subscribe(
     OnStatusChanged, ThreadOption.UIThread);

The fact that you hadn't specified ThreadOption.UIThread and weren't getting a thread exception when adding an item to the status list also indicates that your task is currently on the UI thread.

Upvotes: 1

shriek
shriek

Reputation: 5197

Are you firing the event from a background thread? If yes, that might explain why you are not seeing any updates.

What might help is trying to put the event on the UI thread, you just need to modify the call to Subscribe a bit.

_eventAggregator.GetEvent<PublishStatusEvent>().Subscribe(this.OnStatusChanged, ThreadOption.UIThread);

Upvotes: 0

Related Questions