user5500750
user5500750

Reputation:

Accessing DependencyProperty: The calling thread cannot access this object because a different thread owns it

I would like to load data into my WPF DataGrid when a DependencyProperty value changes. I thought something as simple as this would work but it does not;

public SQLiteDb.Attorney attorney
{
    get { return (SQLiteDb.Attorney)GetValue(attorneyProperty); }
    set {
        SetValue(attorneyProperty, value);
        GetAttorneysIdentitiesAsync(); //Load the data here.
    }
}
public static readonly DependencyProperty attorneyProperty =
    DependencyProperty.Register("attorney", typeof(SQLiteDb.Attorney),
      typeof(AttorneyDetails), new PropertyMetadata(new SQLiteDb.Attorney()));

But I end up getting thread exceptions which I have very little experience about. The method GetAttorneysIdentitiesAsync looks like this which I guess is trying to access the property value from another thread.

public async void GetAttorneysIdentitiesAsync()
{
    AlternativeIdentities = await SQLiteDb.db.Table<SQLiteDb.AttorneyIdentity>().Where(x => x.AttorneyId == attorney.Id).ThenBy(x => x.Id).Take(30).ToListAsync();
    AlternativeIdentitiesGrid.ItemsSource = AlternativeIdentities;
}

I get the exception whenever I try to access the property from within the property class.

The calling thread cannot access this object because a different thread owns it.

Upvotes: 1

Views: 1826

Answers (1)

Clemens
Clemens

Reputation: 128084

You should access the attorny property outside a Task thread:

public async Task GetAttorneysIdentitiesAsync()
{
    var id = attorney.Id;

    AlternativeIdentities = await SQLiteDb.db.Table<SQLiteDb.AttorneyIdentity>()
        .Where(x => x.AttorneyId == id)
        .ThenBy(x => x.Id)
        .Take(30)
        .ToListAsync();

    AlternativeIdentitiesGrid.ItemsSource = AlternativeIdentities;
}

Note also that you should not call anything else than GetValue and SetValue in the CLR wrapper of a dependency property. The reason is explained here.

You should register a PropertyChangedCallback like this:

public SQLiteDb.Attorney attorney
{
    get { return (SQLiteDb.Attorney)GetValue(attorneyProperty); }
    set { SetValue(attorneyProperty, value); }
}

public static readonly DependencyProperty attorneyProperty = DependencyProperty.Register(
    nameof(attorney), typeof(SQLiteDb.Attorney), typeof(AttorneyDetails),
    new PropertyMetadata(new SQLiteDb.Attorney(), attorneyPropertyChanged));

private static async void attorneyPropertyChanged(
    DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    await ((AttorneyDetails)o).GetAttorneysIdentitiesAsync();
}

Upvotes: 5

Related Questions