由于多次实例化,EventHandler为空

时间:2019-06-27 08:13:43

标签: c# wpf event-handling

我的项目遵循MVVM模式。我需要做的是在模型中更改ObservableCollection时更改视图。为此,我想在模型中使用eventHandler并在ViewModel中设置一个侦听器。

我的问题是,我的viewModel类仅实例化一次(当我们首次访问匹配的视图时)。但是我的模型类可以根据用户需求重新实例化。因此,只要用户不触发创建新的模型类,一切都将正常进行。但是在那之后,我的事件处理程序被重新设置为null,并且由于我的ViewModel没有重新实例化,所以我不重新订阅它。因此它保持为空,并且我的viewModel不再知道模型状态。

我当前要做的是通过每次用户访问viewModel时发送一条消息到viewModel来强制视图进行自我更新。 (通过后面的代码onNavigatedTo()),但这并不是最佳选择,因为模型可能没有更改,但是我还是重新计算了一切。

我想知道是否有更好的方法?就像拥有一个静态eventHandler(尝试过但无法使其工作)或能够通过configprojet构造函数在ViewModel类中设置侦听器。

我的模型中的类使用eventHandler。 eventHandler ListeValidationCollectionChanged由我的两个ObservableCollection之一的更改触发。

public class ConfigProjet : NotifyPropertyChanged
{
    public event EventHandler ListeRapportschanged;
    public event EventHandler ListeFicheschanged;

    public event NotifyCollectionChangedEventHandler ListeValidationCollectionChanged;

    public ConfigProjet()
    { }

    private void Validation_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        RaiseValidationCollectionChanged(e);
    }


    private void RaiseValidationCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (ListeValidationCollectionChanged != null)
        {
            ListeValidationCollectionChanged(this, e);
        }
    }

    private void RaiseValidationChanged()
    {
        if (ListeRapportschanged != null)
        {
            ListeRapportschanged(this, EventArgs.Empty);
        }
        else if (ListeFicheschanged != null)
        {
            ListeFicheschanged(this, EventArgs.Empty);
        }
    }

    private ObservableCollection<string> listeFichesAValider;
    public ObservableCollection<string> ListeFichesAValider
    {
        get { return this.listeFichesAValider; }
        set
        {
            if (this.listeFichesAValider != value)
            {
                if (listeFichesAValider != null)
                {
                    //Desabonneemnt
                    listeFichesAValider.CollectionChanged -= Validation_CollectionChanged;
                }

                this.listeFichesAValider = value;
                OnPropertyChanged("ListeFichesAValider");

                if (listeFichesAValider != null)
                {
                    //abonnement
                    listeFichesAValider.CollectionChanged += Validation_CollectionChanged;
                }

                RaiseValidationChanged();
            }
        }
    }

    private ObservableCollection<string> listeRapportsAValider;
    public ObservableCollection<string> ListeRapportsAValider
    {
        get { return this.listeRapportsAValider; }
        set
        {
            if (this.listeRapportsAValider != value)
            {
                if (listeRapportsAValider != null)
                {
                    //Desabonneemnt
                    listeRapportsAValider.CollectionChanged -= Validation_CollectionChanged;
                }

                this.listeRapportsAValider = value;
                OnPropertyChanged("ListeRapportsAValider");

                if (listeRapportsAValider != null)
                {
                    //abonnement
                    listeRapportsAValider.CollectionChanged += Validation_CollectionChanged;
                }

                RaiseValidationChanged();
            }
        }
    }

和我的viewModel类:

public class ProjetsWorkFlowVueModele : NotifyPropertyChanged
{
    public ProjetsWorkFlowVueModele()
    {            
        //used to by-pass my problem, message send by the code-behind on navigationTo event :
        Messenger.Default.Register<ListeFichiersAValiderChangedMessage>(this, OnListeFichiersAValiderChanged);

        Donnees.Instance.ConfigP.ListeFicheschanged += ConfigP_ListeFicheChanged;
        Donnees.Instance.ConfigP.ListeRapportschanged += ConfigP_ListeRapportChanged;
        Donnees.Instance.ConfigP.ListeValidationCollectionChanged += ConfigP_ListeValidationCollectionChanged;

        CreerListeFiche();
        CreerListeRapport();
    }

    private void OnListeFichiersAValiderChanged(ListeFichiersAValiderChangedMessage obj)
    {
        //on rafraichit les listes
        CreerListeFiche();
        CreerListeRapport();
    }

    private void ConfigP_ListeRapportChanged(object sender, EventArgs e)
    {
        CreerListeRapport();
    }

    private void ConfigP_ListeFicheChanged(object sender, EventArgs e)
    {
        CreerListeFiche();
    }

    private void ConfigP_ListeValidationCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        CreerListeFiche();
        CreerListeRapport();
    }
}

编辑1:

我使用的术语,模型,视图和视图模型是指MVVM实现模式。想法是通过使用视图模型将视图(Ui + Ui逻辑)与模型(数据+业务逻辑)分开。因此,所有表示逻辑,视图和状态的数据都在viewModel中计算。这意味着视图的代码背后必须包含尽可能少的逻辑。在MVVM中,视图的dataContext设置为viewModel。然后,将视图的元素绑定到viewModel的元素。 viewModel可以选择使用自己的数据进行绑定,也可以将来自模型的数据公开(在这种情况下,该类必须支持数据绑定)到视图。该模型可以通过INotifyProperty / CollectionChanged进行通信(因此视图或viewModel可以知道任何更改)。

我有两个项目,一个用于模型,另一个用于viewModel +视图。第一个项目(模型)没有对第二个项目的任何引用。但是,第二个可以访问模型的字段。

当我谈到模型,视图等时,我并不清楚,因为有多个模型类在做不同的事情等等。 就我而言,我的模型中有一个类,代表一个项目的数据。因此,当用户从一个项目更改为另一个项目时(由用户界面触发,并由匹配的viewModel触发该命令(引发OnpropertyChanged),然后在我的模型的一个类中(对OnPropertyChanged进行反应),将重新创建该对象。创建另一个模型类的新实例:configProjet)。因此,问题是我创建了configProjet模型类的多个实例,但只创建了我的viewmodel类之一。我的eventHandler(在我的模型类中)是重新实例化的,但不是侦听器(在viewModel类中)。因此,由于没有侦听器订阅,eventHandler保持为空。

我希望我很清楚:x

由于我不是母语人士,我为我的英语感到抱歉。

感谢您的帮助!

0 个答案:

没有答案