Bonjour a tous,

J'explique ma situation c'est assez compliqué, c'est une application wpf, j'utilise le pattern mvvm.

Le contenu de ma fenêtre change en fonction d'une d'une propriété dans la classe qui lui sert de datacontext:

"Fenetre.xaml":
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    <!-- Setting the data context (the ViewModel class linked to this xaml)-->
    <s:SurfaceWindow.DataContext>
        <VM:Switcher x:Name="Switch"/>
    </s:SurfaceWindow.DataContext>
 
    <!-- Declaring specific ressources-->
    <Window.Resources>
 
        <!-- Templating the view model classes in view classes-->
        <!-- LogIn-->
        <DataTemplate DataType="{x:Type VM:VMLogIn}">
            <View:LogIn/>
        </DataTemplate>
 
        <!-- Home-->
        <DataTemplate DataType="{x:Type VM:VMHome}">
            <View:Home/>
        </DataTemplate>
 
    </Window.Resources>
 
    <!--The actual display content-->
    <Grid>
        <!-- Binding the good VM class in the data context class (Switcher)-->
        <ContentPresenter Content="{Binding ViewModelView.CurrentItem}"/>
    </Grid>
Donc grosso modo, dans le code au dessus, je déclare le datacontext (la classe switcher), j’initialise 2 template en disant de remplacer la classe VM:VMLogIn par la classe View:LogIn et la classe VM:VMHome par View:Home. Puis le grid affiche le contenu de ViewModelView.CurrentItem qui peut-être un VM:VMLogIn ou un VM:VMHome, ils seront remplacé a l'affichage par View:LogIn et View:Home.

Dans View:LogIn, j'ai un bouton, le but de la démarche c'est qu'en cliquant dessus cela lève un évènement qui sera attrapé par la classe Switcher et celle ci changera la valeur de ViewModelView.CurrentItem.

"LogIn.xaml":
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
    <UserControl.DataContext>
        <VM:VMLogIn x:Name="ViewModel"/>
    </UserControl.DataContext>
    <Grid>
        <Custom:SurfaceButton x:Name="ConnectButton" Content="Connect" Command="{Binding connect}" />
   </Grid>
Donc ici je déclare le data context (avec la classe VM:VMLogin), puis je pose un bouton dont la commande et bindé sur la commande "connect" du data context.

Du cote du ViewModel voila ce qu'il se passe,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class VMLogIn : ViewModelBase
    {
 
        /*
         * la commande associe' au bouton du xaml
         */
        private ICommand __connect;
        public ICommand connect
        {
            get
            {
                if (__connect == null)
                    __connect = new RelayCommand<object>(connection, null);
                return __connect;
            }
        }
 
        /*
         * L'event a liberer si l'on souhaite changer de page.
         */ 
        public event EventHandler<MoveToEventArgs> moveTo;
 
        /*
         * La fonction qui libere l'event avec le bon argument indiquant 
         * la page que l'on souhaite afficher
         */ 
        public void connection(object param)
        {
            MoveToEventArgs e = new MoveToEventArgs("home");
            EventHandler<MoveToEventArgs> handler = moveTo;
 
            if (handler != null)
                handler(this, e);
        }
    }
Donc ici, il y a une ICommand qui lorsquelle est activé apelle la fonction connection qui libere l'event moveTo avec l'argument "home".

Du coté de la classe Switcher (qui est le datacontext de fenetre.xaml) on a ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
        /*
         * The collections of VM classes (representing Views)
         */
        private ObservableCollection<ViewModelBase> _ViewModels;
        public ObservableCollection<ViewModelBase> ViewModels[...]
 
        private ICollectionView _ViewModelView;
        public ICollectionView ViewModelView[...]
 
        /*
         * Creating the collection of view, and linking the source 
         * of the binded collection to it
         */ 
        public Switcher()
        {
            VMLogIn login = new VMLogIn();
            login.moveTo += new EventHandler<MoveToEventArgs>(Switcher_moveTo); //ceci est important
 
            ViewModels = new ObservableCollection<ViewModelBase>()
            {
                login,
                new VMHome()
            };
            ViewModelView = CollectionViewSource.GetDefaultView(ViewModels);
        }
 
        void Switcher_moveTo(object sender, MoveToEventArgs e)
        {
            this.moveTo(e.page);
        }
 
        /*
         * this function change the value of ViewModelView.current
         * so the screen change.
         */
        private void moveTo(string page)
        {
            if (ViewModelView != null)
            {
                switch (page)
                {
                    case "logIn":
                        ViewModelView.MoveCurrentToPosition((int)View.LOGIN);
                        break;
                    case "home":
                        ViewModelView.MoveCurrentToPosition((int)View.HOME);
                        break;
                }
            }
        }
Mon probleme c'est que cela ne fonctionne pas, quand je clique sur le bouton de View:LogIn, la commande est bien appelé mais, mais l'event moveTo est égal a null.

Donc cela signifie que le dataContext de View:LogIn n'est pas la classe que j'ai instancié dans la classe Switcher mais une nouvelle.

Comment faire pour que le data context cible la bonne instance et n'en crée pas une nouvelle?

merci d'avance.