Wpf 在viewmodel中执行函数并实时刷新视图

Wpf 在viewmodel中执行函数并实时刷新视图,wpf,mvvm,mvvm-light,Wpf,Mvvm,Mvvm Light,我的MVVM应用程序有一个小问题 我在viewmodel中有一个修改集合的函数。此集合绑定到视图以显示datagrid。当用户单击按钮时,函数将修改集合,但可能需要几分钟时间,并且视图不会刷新 我的问题是如何执行此函数以实时刷新视图 在另一个程序中,我使用了dispatcher,但它位于视图的代码后面,没有绑定 谢谢 编辑: 型号: public class Composants : INotifyPropertyChanged { private string _nom; p

我的MVVM应用程序有一个小问题

我在viewmodel中有一个修改集合的函数。此集合绑定到视图以显示datagrid。当用户单击按钮时,函数将修改集合,但可能需要几分钟时间,并且视图不会刷新

我的问题是如何执行此函数以实时刷新视图

在另一个程序中,我使用了dispatcher,但它位于视图的代码后面,没有绑定

谢谢

编辑:

型号:

public class Composants : INotifyPropertyChanged
{
    private string _nom;

    public string Nom
    {
        get { return _nom; }
        set { _nom = value; OnPropertyChanged("Nom"); }
    }

}
视图模型:

public class PageSynchroViewModel : INotifyPropertyChanged
{
    public void SynchroniserComposants()
    {
        foreach (var comp in _selectedVersion.ListeComposants)
        {
            comp.Nom = "";
        }
}
视图(我没有列出所有代码):


[...]
[...]

尝试使用
可观察的集合,而不是您现在使用的集合

这将导致每当从集合中添加或删除项时,视图都会更新

只需记住,当与
ObservableCollection
交互以调用Dispatcher时,否则会出现线程访问异常

下面是我用来测试这个的代码

XAML


它更新了视图中的Nom。

几分钟?你们能发布你们的代码吗?几秒钟后,用户点击“同步”按钮时并没有任何信息。我在主窗口上有一个小的装载指示器。当用户单击synchro按钮时,PageSynchroViewModel将向主窗口发送一条消息(带有mvvm指示灯),以显示加载指示器,但它不会显示。我不会添加或删除项目,只需更改项目属性,每个属性都会调用propertyChanged事件。我用于集合的模型实现inotifypropertychange在处理结束时,尝试使用集合的名称调用
PropertyChanged
事件,如果在集合项上使用
INotifyPropertyChanged
,则它们应该在视图模型中出现的
observedcollection中冒泡出现。尽管您可能希望使用相关代码更新您的问题。它可能会吸引更多的答案。您需要在添加到您的
ObservableCollection
:)@user1069516的每个项目上注册
PropertyChanged
事件。我已经用一些代码更新了我的答案,您可能会看到您遗漏了什么。
<Page x:Class="Centre_de_synchronisation.Vues.PageSynchro"
  [...]
  xmlns:app="clr-namespace:Centre_de_synchronisation.Classes" mc:Ignorable="d"
  d:DesignHeight="531" d:DesignWidth="778"
Title="PageSynchro" Background="{x:Null}">
<Canvas>
    [...]
    <DataGrid Name="GridComposants" Style="{StaticResource DatagridStyle}"  ItemsSource="{Binding ListeComposants}" AutoGenerateColumns="False" Canvas.Left="12" Canvas.Top="201" Height="285"  Width="754"  >
        <DataGrid.Columns>
            <DataGridTextColumn
       Header="Nom"
       Binding="{Binding Nom}"
       Width="150"
               IsReadOnly="True"/>
            [...]
    </DataGrid>
    <Button Name="BoutonSynchro" Style="{StaticResource MessageBoxButtonStyle}" Content="Synchroniser" Height="27" Width="107" Command="{Binding BoutonSynchro}" CommandParameter="GridComposants" Visibility="{Binding Etat, Converter={StaticResource VisibilityConverter}}"/>
</Canvas>
<Window.Resources>
    <loc:MyViewModel x:Key="ViewModel" />
</Window.Resources>
<Canvas DataContext="{StaticResource ViewModel}">
    <DataGrid ItemsSource="{Binding Collection}"
              Width="150"
              Height="200">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Nom"
                                Binding="{Binding Nom}"
                                Width="150"
                                IsReadOnly="True" />
        </DataGrid.Columns>
    </DataGrid>
    <Button Command="{Binding DoStuffCommand}"
            Canvas.Bottom="0"
            Canvas.Right="0">Stuff</Button>
</Canvas>
public class MyViewModel
{
    public ObservableCollection<MyModel> Collection { get; set; }

    public ICommand DoStuffCommand { get; set; }

    public MyViewModel()
    {
        this.Collection = new ObservableCollection<MyModel>();

        for (int i = 0; i < 10; i++)
        {
            Collection.Add(new MyModel { Nom = i.ToString() });
        }

        this.DoStuffCommand = new RelayCommand(DoStuff);
    }

    private void DoStuff()
    {
        foreach (var item in Collection)
        {
            item.Nom = item.Nom + ".";
        }
    }
}
public class MyModel : INotifyPropertyChanged
{
    private string nom;

    public string Nom
    {
        get { return nom; }
        set
        {
            nom = value;
            RaiseChanged("Nom");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaiseChanged(string propertyName)
    {
        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}