Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TreeDataGrid does not update when model properties change #128

Open
SuperJMN opened this issue Sep 8, 2022 · 6 comments
Open

TreeDataGrid does not update when model properties change #128

SuperJMN opened this issue Sep 8, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@SuperJMN
Copy link
Contributor

SuperJMN commented Sep 8, 2022

Describe the bug
Given an underlying model that implements INotifyPropertyChanged, the TreeDataGrid doesn't update when the model is updated.

To Reproduce

**For convenience, I've create a repo ready to test the issue:
https://github.com/SuperJMN-Tutorials/TreeDataGrid-Out-Of-Sync

If you want to do it yourself:

  1. Create a new MVVM application.
  2. Add the TreeDataGrid package.
  3. Add this code to MainViewModel.
public class MainWindowViewModel : ViewModelBase
{
    public MainWindowViewModel()
    {
        var collection = new ObservableCollection<Model>();
        var model = new Model("Hello!");
        collection.Add(model);
        Source = new FlatTreeDataGridSource<Model>(collection)
        {
            Columns =
            {
                new TextColumn<Model, string>("Text", x => x.Text),
            }
        };

        Observable.Timer(TimeSpan.FromSeconds(2))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => model.Text = "How are you?");
    }

    public FlatTreeDataGridSource<Model> Source { get; }
}

public class Model : ViewModelBase
{
    private string text;

    public Model(string text)
    {
        Text = text;
    }

    public string Text
    {
        get => text;
        set => this.RaiseAndSetIfChanged(ref text, value);
    }
}
  1. Add this code to MainWindow.axaml:
 <TreeDataGrid Source="{Binding Source}" />
  1. Run the project.

Expected behavior
After 2 seconds, the data in the DataGrid should display "How are you?". However, it shows the initial text "Hello".

NOTES
Interestingly enough, the TreeDataGrid starts to behave correctly when you click the column header. It seems that sorting a column makes it update.

Desktop (please complete the following information):

  • OS: Windows 11

Additional context
Avalonia 0.10.18.

@SuperJMN SuperJMN added the bug Something isn't working label Sep 8, 2022
@maxkatz6 maxkatz6 transferred this issue from AvaloniaUI/Avalonia Sep 8, 2022
@maxkatz6
Copy link
Member

maxkatz6 commented Sep 8, 2022

@grokys @Takoooooo

@CShark
Copy link

CShark commented Dec 16, 2022

For anyone looking for a workaround - some reflection magic on private methods does allow to refresh the cells - namely calling CollectionChanged on the HierarchicalRows-Instance. You'll have to adjust the type though to match your HierarchicalTreeDataGridSource. In my case it was enough to call it every time the selection changes.

var rows = (HierarchicalRows<Entry>)EntriesTree.GetType()
    .GetMethod("GetOrCreateRows", BindingFlags.NonPublic | BindingFlags.Instance)
    .Invoke(EntriesTree, null);
var evt = (NotifyCollectionChangedEventHandler)rows.GetType().GetField("CollectionChanged",
    BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(rows);

if (evt != null) {
    foreach (var handler in evt.GetInvocationList()) {
        handler.Method.Invoke(handler.Target,
            new object[]
                { rows, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset) });
    }
}

@boomer41
Copy link

boomer41 commented Jun 17, 2023

Any update on this one? This makes the grid unusable when relying on INotifyPropertyChanged for the data.

@boomer41
Copy link

boomer41 commented Jun 18, 2023

@SuperJMN

So, I went on and went to debug the missing IPropertyChanged subscription.
Turns out, in v10, the TreeDataGridCell does indeed not subscribe.

However, this issue is already fixed in the latest master branch for v11 by commit 58394ad "Implement cell editing for text cells."

When adding the following code to the sample project on v11 to the Country model's constructor, we can observe the desired effect. I also made the model a ReactiveObject for convenience.

The columns refresh as expected. Now just to wait until v11 :)

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

                    Dispatcher.UIThread.Post(() =>
                    {
                        Name += "1";
                        this.RaisePropertyChanged(nameof(Name));
                    });
                }
            });

@boomer41
Copy link

boomer41 commented Jun 18, 2023

Okay, there STILL is a bug in the latest v11...
The changed value only gets rendered every second property changed event. :(

EDIT: Was my fault. Works as intended.

@alexandrehtrb
Copy link

This problem still happens for me with a TextColumn; my workaround was to use a TemplatedColumn...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants