A191919
A191919

Reputation: 3442

WPF MVVM async loading notify

I have two views in window one of them load data asynchronously. How can i Notify second view that data is loaded and it need to update data in label? Make singleton with callback?

MainWindow.xaml

    <Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <views:FirstView Grid.Column="0"></views:FirstView>
        <views:SecondView Grid.Column="1"></views:SecondView>
    </Grid>
</Grid>

FirstView.xaml

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Button Grid.Column="0" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Command="{Binding LoadData}"/>
    <ListView ItemsSource="{Binding Items}" Grid.Column="1">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Label Content="{Binding Name}" Grid.Column="0"></Label>
                    <Label Content="{Binding Hours}" Grid.Column="1"></Label>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

FirstViewModel:

 public class FirstViewModel : ViewModelBase
{
    /// <summary>
    /// Initializes a new instance of the FirstViewModel class.
    /// </summary>
    public ObservableCollection<ItemStruct> Items { get; set; }
    public ICommand LoadData { get; set; }
    public FirstViewModel()
    {
        LoadData = new RelayCommand(() => LongLoadData());
        Items = new ObservableCollection<ItemStruct>();
        Items.Add(new ItemStruct { Name="First",Hours="Loading"});
        Items.Add(new ItemStruct { Name = "Second",Hours="Loading" });
    }
    public void LongLoadData()
    {
        Action Load = new Action(AsyncLoad);
        IAsyncResult result = Load.BeginInvoke(null, null);
    }

    private void AsyncLoad()
    {

        foreach (ItemStruct item in Items)
        {
            Random rnd = new Random();
            System.Threading.Thread.Sleep(3000);
            item.Hours = rnd.Next(1, 100).ToString();
        }
    }
}

SecondView.xaml:

 <Grid>
    <ListView ItemsSource="{Binding Items}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Label Content="{Binding Name}" Grid.Column="0"></Label>
                    <Label Content="{Binding Hours}" Grid.Column="1"></Label>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

SecondViewModel:

    public class SecondViewModel : ViewModelBase
{
    public ObservableCollection<ItemStruct> Items { get; set; }
    public SecondViewModel()
    {
        Items = new ObservableCollection<ItemStruct>();
        Items.Add(new ItemStruct { Name="First",Hours="Loading"});
        Items.Add(new ItemStruct { Name = "Second",Hours="Loading" });
    }
}

Upvotes: 1

Views: 805

Answers (1)

Anatolii Gabuza
Anatolii Gabuza

Reputation: 6260

You can use MvvmLight Messenger for communication between VM's. Inject it into child ViewModels.

public FirstVieModel(IMessenger messenger)
{
   this.messenger = messenger;
}

When data loaded invoke messenger(send) with proper message.

this.messenger.Send<SomethingLoadedMessage>(new SomethingLoadedMessage(..));

In reciever ViewModel handling is also quite simple:

this.messenger.Register<SomethingLoadedMessage>(this, OnSomethingLoaded);

Using messenger generally is a good practice when it comes to buildng loosly coupled multi-conpoment WPF apps.

Upvotes: 2

Related Questions