从另一个帮助器类更新视图模型的可观察集合

时间:2022-02-19 16:05:30

i have a ViewModel with an ObservableCollection, i have a long function that i will use to update the ObservableCollection items however the function is so long and i don't want to put it inside the ViewModel.

我有一个带有ObservableCollection的ViewModel,我有一个很长的函数,我将用它来更新ObservableCollection项,但是函数太长了,我不想把它放在ViewModel中。

i want to do the updates directly on the ObservableCollection so that i can see the changes on my view while the process is running.

我想直接在ObservableCollection上进行更新,这样我就可以在进程运行时看到我视图的更改。

i thought about the followig

我想到了关注

  • sending the ObservableCollection by ref
  • 通过ref发送ObservableCollection
  • sending the current item to a function and return the updated object
  • 将当前项发送到函数并返回更新的对象
  • making my ObservableCollection static
  • 使我的ObservableCollection静态
  • puting the update function in my ViewModel but that will make my ViewModel big and messy
  • 将更新功能放在我的ViewModel中,但这将使我的ViewModel变得庞大而混乱

there will be alot of different functions that will work on this collection, in such cases what is the best programing practice?

将会有很多不同的功能可用于此集合,在这种情况下,什么是最好的编程实践?

1 个解决方案

#1


1  

If you are processing the data and then passing the processed data to the View then I think the below option should be one possible solution.

如果您正在处理数据然后将处理过的数据传递给View,那么我认为以下选项应该是一种可能的解决方案。

The below solution will process the data while the view is also notified of the change simultaneously.

以下解决方案将处理数据,同时还向视图通知更改。

public class MyViewModel : INotifyPropertyChanged
{
    private ObservableCollection<string> _unprocessedData = new ObservableCollection<string>();
    private ObservableCollection<string> _processedData = new ObservableCollection<string>();
    private static object _lock = new object();
    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<string> Collection { get { return _processedData; } }//Bind the view to this property

    public MyViewModel()
    {
        //Populate the data in _unprocessedData
        BindingOperations.EnableCollectionSynchronization(_processedData, _lock); //this will ensure the data between the View and VM is not corrupted
        ProcessData();
    }

    private async void ProcessData()
    {
        foreach (var item in _unprocessedData)
        {
            string result = await Task.Run(() => DoSomething(item));
            _processedData.Add(result);
            //NotifyPropertyChanged Collection
        }
    }

    private string DoSomething(string item)
    {
        Thread.Sleep(1000);
        return item;
    }
}

The DoSomething method can be defined in some other class outside the ViewModel.

可以在ViewModel之外的其他类中定义DoSomething方法。

I hope this helps.

我希望这有帮助。

#1


1  

If you are processing the data and then passing the processed data to the View then I think the below option should be one possible solution.

如果您正在处理数据然后将处理过的数据传递给View,那么我认为以下选项应该是一种可能的解决方案。

The below solution will process the data while the view is also notified of the change simultaneously.

以下解决方案将处理数据,同时还向视图通知更改。

public class MyViewModel : INotifyPropertyChanged
{
    private ObservableCollection<string> _unprocessedData = new ObservableCollection<string>();
    private ObservableCollection<string> _processedData = new ObservableCollection<string>();
    private static object _lock = new object();
    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<string> Collection { get { return _processedData; } }//Bind the view to this property

    public MyViewModel()
    {
        //Populate the data in _unprocessedData
        BindingOperations.EnableCollectionSynchronization(_processedData, _lock); //this will ensure the data between the View and VM is not corrupted
        ProcessData();
    }

    private async void ProcessData()
    {
        foreach (var item in _unprocessedData)
        {
            string result = await Task.Run(() => DoSomething(item));
            _processedData.Add(result);
            //NotifyPropertyChanged Collection
        }
    }

    private string DoSomething(string item)
    {
        Thread.Sleep(1000);
        return item;
    }
}

The DoSomething method can be defined in some other class outside the ViewModel.

可以在ViewModel之外的其他类中定义DoSomething方法。

I hope this helps.

我希望这有帮助。