0

I have this Singleton that hold my ObservableCollection<MyData> as a memeber:

public sealed class Singleton
{
    private static volatile Singleton instance;
    private static object syncRoot = new Object();

    public ObservableCollection<MyData> Files { get; private set; }

    private Singleton()
    {
        Files = new ObservableCollection<MyData>();
    }

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new Singleton();
                }
            }

            return instance;
        }
    }
}

Declaration from main form class:

ObservableCollection<MyData> Files;

And here after the constructor:

Files= Singleton.Instance.Files;

XAML:

<ListView ItemsSource="{Binding Files}" />

Now when the user choose files i want to check each file:

private static void Check(IEnumerable<string> files)
{
    CancellationTokenSource tokenSource = new CancellationTokenSource();
    CancellationToken token = tokenSource.Token;
    Task task = Task.Factory.StartNew(() =>
    {
        try
        {
            Parallel.ForEach(files,
            new ParallelOptions
            {
                MaxDegreeOfParallelism = 1
            },
        file =>
        {
            ProcessFile(file);
        });
        }
        catch (Exception)
        { }

    }, tokenSource.Token,
       TaskCreationOptions.None,
       TaskScheduler.Default).ContinueWith
        (t =>
        {

        }
, TaskScheduler.FromCurrentSynchronizationContext()
);
}

And:

private static void ProcessFile(string file)
{
    // Lets assume that i want to add this file into my `ListView`
    MyData data = new .....
    Singleton.Instance.Files.Add(data);
}

So after this point when i am add files into my list nothing happenning.

david hol
  • 1,272
  • 7
  • 22
  • 44
  • did you set the `DataContext` of the main form class? E.g. `Files= Singleton.Instance.Files; this.DataContext = this;` – Markus Gilli Nov 12 '15 at 20:39
  • Yes, after Files = Singleton.Instance.Files; – david hol Nov 12 '15 at 20:45
  • Check if there is an TargetInvokationException in `ProcessFile`. Adding items to an `ObservableCollection<>` must happen in the same thread as the collection is created. So in your case the UI-thread... You can use `Application.Current.Dispatcher.Invoke(() => Singleton.Instance.Files.Add(data))` to ensure. – Markus Gilli Nov 12 '15 at 20:50
  • No exception, i also try to use this Application.Current.Dispatcher... and i can see via the dubugger that my list is filled. – david hol Nov 12 '15 at 21:01
  • Sure there is no exception? You catch everything without any logging in the code above: `catch (Exception) {}` – Markus Gilli Nov 12 '15 at 21:05
  • Sure, i am using try catch and there is no exception. – david hol Nov 12 '15 at 21:12
  • WPF can't bind to fields. Make your files collection in main form a property... – Markus Gilli Nov 12 '15 at 21:45
  • What do you mean make your files collection in main form a property ? – david hol Nov 13 '15 at 04:38
  • Just add get and set to it: `ObservableCollection Files { get; private set;}` – Markus Gilli Nov 13 '15 at 05:25
  • I think my problem is other, please see this: http://stackoverflow.com/questions/33688280/bind-my-object-inherit-into-listview – david hol Nov 13 '15 at 08:41

1 Answers1

0

Using your code above i was able to reproduce the issue you describe. The problem is that WPF cannot bind to fields, see this question for more details. All you need to do is to change the ObservableCollection<MyData> in the code behind of your main form to a property instead of a field.

public partial class MainWindow : Window
{
    public ObservableCollection<MyData> Files { get; private set; }
Community
  • 1
  • 1
Markus Gilli
  • 227
  • 2
  • 8