Dynamic UI Update

Daz66

Active member
Joined
May 17, 2020
Messages
40
Programming Experience
Beginner
Hi all,

I have a UserControl which is primarily a DataGrid which is populated by ObservableCollection.

C#:
Dispatcher.CurrentDispatcher.Invoke(() =>
{
    GetAllExpenses = new ObservableCollection<ExpensesBaseClass>(_repository.GetAll());
});

private ObservableCollection<ExpensesBaseClass>? _getAllExpenses;
public ObservableCollection<ExpensesBaseClass>? GetAllExpenses
{
    get { return _getAllExpenses; }
    set
    {
        _getAllExpenses = value;
        OnPropertyChanged(nameof(GetAllExpenses));
    }
}


My BaseClass inherits from ObservableObject
C#:
public partial class ExpensesBaseClass : ObservableObject,IExpensesModel
{

    [ObservableProperty]
    private int _id;
    
    //Rest of properties

When I call my Add method, the view(UserControl) doesn't update dynamically but my Edit method does.

The code is very similar for both, they both update the repo successfully but I'm having to call a method to update the view after the Add

C#:
public void ReloadData()
{
    Application.Current.Dispatcher.Invoke(() =>
    {
        var newData = new ObservableCollection<ExpensesBaseClass>(_repository.GetAll());

        FilteredExpenses = newData;
        OnPropertyChanged(nameof(FilteredExpenses));
    });
}

I'm populating the UserControlview like so, the ExpensesViewModel is being injected into the MainWindow constructor:
C#:
private object? _currentView;

public object? CurrentView
{
    get { return _currentView; }
    set
    {
        if (_currentView != value)
        {
            _currentView = value;
            OnPropertyChanged(nameof(CurrentView));
        }
    }
}

[RelayCommand]
public void ExpensesView()
{
    CurrentView = ExpVM;
}


<ContentControl x:Name="test"
                Grid.Row="1"
                Grid.Column="1"
                Margin="0,12,12,12"
                Content="{Binding CurrentView}">
    <ContentControl.Resources>
        <DataTemplate DataType="{x:Type viewModels:ExpensesViewModel}">
            <auc:ExpensesViewUserControl />
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>
}
\

This DataTemplate also loads with App.xaml.cs but I have it in the CC for testing too.

The Edit is working fine, only difference is, is that the SelectedItem of the Grid is being passed through the constructor then updated, the UI updates dynamically but the Add does not.

Any pointers appreciated, there is obviously lots of code and didn't want to put it all in the first question, so ask what you need to see and I will post it.

Thanks in advance.
 
Why are you creating a brand new observable collection each time? The point of an observable collection is that it will notify the UI when changes are made to items, and when new items are added or removed from the collection.

Perhaps the issue is that your repo is not notifying the observable collection when items are added or removed from it?
 
This works, probably more of a workaround, but the collection won't update without a nudge.

C#:
private ObservableCollection<ExpensesBaseClass>? _getAllExpenses;

public ExpensesViewModel(IRepository<ExpensesBaseClass> expensesRepository)
{
    _repository = expensesRepository;

    _getAllExpenses = new ObservableCollection<ExpensesBaseClass>();

    Dispatcher.CurrentDispatcher.Invoke(() =>
    {
        foreach (var expense in _repository.GetAll())
        {
            _getAllExpenses.Add(expense);
        }
    });

    Task.Run(async () =>
    {
        while (true)
        {
            await Task.Delay(TimeSpan.FromSeconds(1)); 
            var updatedExpenses = _repository.GetAll();

            UpdateAllExpenses(updatedExpenses);
        }
    });

private void UpdateAllExpenses(IEnumerable<ExpensesBaseClass> updatedExpenses)
{
    Application.Current.Dispatcher.Invoke(() =>
    {
    _getAllExpenses.Clear();
    foreach (var expense in updatedExpenses)
    {
    _getAllExpenses.Add(expense);
    }
    });
}
 

Latest posts

Back
Top Bottom