1

I'm trying to do a program to insert some materials like iron and steel and then show them from an interface developed in WPF.

EDIT :

    public class MaterialRegistryPageVm : PageViewModel
    {
       private ObservableCollection<Material> _materials;
       private readonly object _materialsLock = new object();
       private Material _material;
       private MaterialThickness _materialThickness;
       private string _materialFilterFileName;

       public ObservableCollection<Material> Materials
       {   
           get
           {
               _materialCollectionView = CollectionViewSource.GetDefaultView(_materials);
               _materialCollectionView.Filter = _DoesMaterialMatchFileNameFilter;

               return _materials;
           }
               set => Set(ref _materials, value);
       }
       private ICollectionView _materialCollectionView;

       private async void _AddMaterialExecution()
       {
          var material = new Material
          {
             TimeStamp = DateTime.Now
          };

          var dialog = new MaterialDialog(material);
          var result = await DialogHost.Show(dialog, "RootDialog");
          if (!result.Equals(true))
          return;

          material.Name = material.Name.Trim();

          _AddMaterial(material);
          lock (_materialsLock)
          Application.Current.Dispatcher.BeginInvoke(new Action(() => this.Materials.Add(material))); 
        
          Material = material;

          if (Mode == ContextMode.Online)
            await _NotifyAddMaterialAsync(material);
       }

I have a DataGrid which is populating data from ViewModel by asynchronous method. My DataGrid is:

<Grid Grid.Row="0" Margin="8">
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<StackPanel Grid.Column="0" Orientation="Horizontal">
    <Button Command="{Binding AddMaterialCommand, Mode=OneTime}" ToolTip="{DynamicResource Localization.ToolTip.CreateMaterial}" Height="48" Width="48" Style="{StaticResource MaterialDesignOutlinedButton}" materialDesign:ButtonAssist.CornerRadius="0" Padding="0" Margin="0">
        <materialDesign:PackIcon Kind="Add" Height="24" Width="24" />
    </Button>

        <Button Command="{Binding RemoveMaterialCommand, Mode=OneTime}" ToolTip="{DynamicResource Localization.ToolTip.DeleteMaterial}" Width="48" Height="48" Style="{StaticResource MaterialDesignOutlinedButton}" materialDesign:ButtonAssist.CornerRadius="0" Padding="0" Margin="2 0 0 0">
            <materialDesign:PackIcon Kind="Minus" Height="24" Width="24" />
        </Button>
    </StackPanel>
        <TextBlock Grid.Column="1" Text="{DynamicResource Localization.Materials}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="32 0 16 0" Style="{StaticResource MaterialDesignHeadline5TextBlock}" />
    </Grid>

On Application.Current.Dispatcher.BeginInvoke(new Action(() => this.Materials.Add(material)));

I've got this error: System.NotSupportedException: 'this type of collectionview does not support changes to its sourcecollection from a thread different from the Dispatcher thread'.

I've read these threads How do I update an ObservableCollection via a worker thread? and This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread

but I don't understand so much, indeed I tried to change Materials.Add(material); in Application.Current.Dispatcher.BeginInvoke(new Action(() => this.Materials.Add(material))); as suggested but I have got the same error.

Errors : Stack Trace Stack Trace 2

Francesco
  • 11
  • 2
  • What have you tried to do to fix your problem from linked topics answers? `async void` for method other than event handler is also a problem. You didn't provide debugging details: code is not full, exception is without stack trace, you didn't mark problematic line, etc. See [mcve]. – Sinatr Nov 05 '20 at 10:43
  • @Sinatr maybe due to my bad english I couldn't be able to explain what did I do. In the final part I've written what I've tried to do from the topics, and the error line is written too, below the wpf code. The edit was before your reply, I didn't change anything after that. What other part of code do you need? I posted my method to add an item because the error is there – Francesco Nov 05 '20 at 11:08
  • I don't know how this happened, maybe I just was blind and haven't seen "I tried" part. Sorry. But still we don't know what is happening without full stack trace. You assume it's `Materials.Add(material)` line, but it should then be working correctly after invoking and it seems didn't. The *"got the same error"* without stack trace is hard to prove, maybe you have another place what modifies collection, we don't know. – Sinatr Nov 05 '20 at 11:39
  • How this collection is created? How collection view is created? How above method is called? – Sinatr Nov 05 '20 at 11:44
  • firstly can you change your method from `async void` to `async Task`, also please show the code for the method `_AddMaterial(material);`. Also why the `lock`, is it necessary to lock - is this a shared resource accessed by multiple threads? – Bandook Nov 05 '20 at 12:05
  • Line 17? What line is that in your example? And how and from where is `_AddMaterialExecution()` called? – mm8 Nov 05 '20 at 12:07
  • @Sinatr I edited the post and added more informations about the code and the stack trace – Francesco Nov 05 '20 at 13:14
  • @Bandook yes, my resources are accessed by multiple threads – Francesco Nov 05 '20 at 13:14
  • @mm8 yes, I meant on the code I posted. I corrected – Francesco Nov 05 '20 at 13:15

0 Answers0