WPF MVVM异步加载通知

时间:2015-07-23 11:46:26

标签: c# wpf xaml mvvm

我在窗口中有两个视图,其中一个视图异步加载数据。如何通知第二个视图数据已加载并且需要更新标签中的数据? 使用回调制作单身人士?

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" });
    }
}

1 个答案:

答案 0 :(得分:2)

您可以使用 MvvmLight Messenger进行VM之间的通信。将其注入孩子ViewModels

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

加载数据时,使用正确的消息调用messenger(发送)。

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

收件人中,ViewModel处理也非常简单:

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

buildng loosly coupled multi-conpoment WPF apps来说,使用信使通常是一种很好的做法。