Bonjour à tous,
C'est pas dans mon habitude de venir poser des questions, en général je finis toujours par trouver ce qui cloche dans mon code mais là je dois avouer qu'après 3 jours de recherches et de tutoriaux j'ai toujours pas tout compris de mon/mes erreur(s).
Je débute en WPF, je suis pas un grand fan du XML sous toutes ses formes Mais ce truc permet tellement de customisation et un rendu UI tellement + attractif que WinForm que je suis convaincu de la rentabilité du temps investi pour créer mon appli
Je vous explique mon soucis:
J'ai suivi quelques tutoriaux sur le pattern MVvM, assez bien expliqués dans l'ensemble. Je commence à me familiariser avec les data binding (avant je m'en servais jamais XD) et je crois que c'est là que j'ai un soucis.
Je veux créer une appli qui permet de virtualiser une arborescence "commune" à 3 disques durs différents. Le but est de créer une sorte de catalog de contenu qui ne soit pas dépendant de l'arborescence des disques, mais qui me permette de créer cette arborescence directement à partir de l'appli, en simultanée sur les 3 disques (et du coup d'uniformiser leur contenu si besoin, etc).
J'en suis à la rédaction du code qui va lire le fichier XML (catalog). Le truc c'est que je ne pense pas avoir besoin d'un UserControl (View) pour mon TreeView, j'ai juste besoin de mes Models et ViewModels pour récupérer les infos que je veux afficher dans le TreeView que je customiserais grâce à un HierarchicalDataTemplate.
Mon soucis c'est que je remplis bien mon ViewModel avec mes entrées XML, mais dans le treeview je vois que le type de mon viewmodel apparaitre (je sais que ça fait ça dans le cas d'absence de DataTemplate (en parsant par défaut le ToString() de ma classe)... mais moi j'en ai spécifié un !).
Bref, très de bavardage, voici mon code, en espérant que vous puissiez éclairer ma lanterne qui s'est éteinte à l'entrée de ce tunnel bien noir ! :p
-- Classe Data [DataClasses\RepositoryFolder.cs]
Déjà est-ce correct que ma classe "data" soit si fortement typé sur le type d'ifnos en entrée ? (xmlnode) ou dois-je m'y prendre autrement ?
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 public class RepositoryFolder { string name; string repositoryPath; string svnPath; string wipPath; string finalPath; bool hasChilds; int assetCount; /* set / get */ public RepositoryFolder(XmlNode _folderInfo) { name = _folderInfo.Attributes["name"].Value; repositoryPath = _folderInfo.NamespaceURI.ToString(); svnPath = _folderInfo.Attributes["svnpath"].Value; wipPath = _folderInfo.Attributes["wippath"].Value; finalPath = _folderInfo.Attributes["finalpath"].Value; // Default values; hasChilds = _folderInfo.HasChildNodes; XmlNodeList assetChilds = _folderInfo.SelectNodes("FOOAsset"); AssetCount = assetChilds.Count; } }
-- ViewModels [ViewModelClasses\RepositoryViewItemViewModel.cs]
C'est une version "améliorée" de ViewModelBase que j'ai trouvé sur le net ( ici si je me souviens bien).
J'ai just modifié le type d'éléments des view items pour qu'ils concordent avec mes Viewmodels.
-- ViewModels [ViewModelClasses\RepositoryViewModel.cs]
La classe parente qui initialise les premiers nodes de mon treeview. Dans l'exemple donné dans le lien ci-dessus ça correspond à DriveViewModel (qui liste les sous-dossiers d'un disque dur)
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 class RepositoryViewModel { private ObservableCollection<RepositoryFolderViewModel> repositoryStructure; private String repositoryXMLDocumentPath; public String XMLDocumentPath { get; set; } public RepositoryViewModel() { this.BuildListing(); } public void BuildListing() { // Getting the first folders repositoryXMLDocumentPath = XMLDocumentPath != null ? XMLDocumentPath : @"I:\V13\Tools\FOOAssetsManager\FOOAssetsManager\FOOAssetsManager\TestRepository.xml"; if (File.Exists(repositoryXMLDocumentPath)) { // loading the XML content repositoryStructure = new ObservableCollection<RepositoryFolderViewModel>(); XmlDocument doc = new XmlDocument(); XmlTextReader reader = new XmlTextReader(repositoryXMLDocumentPath); doc.Load(reader); // Getting the first level of folders and creating the list to return XmlNodeList firstLevelNodeList = doc.SelectNodes("Repository/Folder"); foreach (XmlNode node in firstLevelNodeList) { RepositoryFolder Folder = new RepositoryFolder(node); RepositoryFolderViewModel FolderViewModel = new RepositoryFolderViewModel(Folder); repositoryStructure.Add(FolderViewModel); } } } public ObservableCollection<RepositoryFolderViewModel> RootFolders { get { return repositoryStructure; } } }
-- ViewModels [ViewModelClasses\RepositoryFolderViewModel.cs]
je ne me suis pas encore attelé à l'écriture de l'expand car pour l'instant j'aimerais déjà voir les premiers éléments s'afficher..., et que j'ai pas encore trop d'idée sur comment faire ça pour l'instant. Si vous avez une astuce pour récupérer le XPath d'un XmlNode dans le document je suis preneur !!
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 public class RepositoryFolderViewModel : RepositoryTreeViewItemViewModel { readonly RepositoryFolder currFolder; public RepositoryFolderViewModel(RepositoryFolder _folder, RepositoryFolderViewModel _parentFolder = null) : base(_parentFolder, true) { currFolder = _folder; } public String Name { get { return currFolder.Name; } } protected override void LoadChildren() { Console.WriteLine("Et là il faut charger les fils..."); } }
Enfin, voici le code que j'ai mis dans ma MainWindow:
Le Loaded="TreeView_Loaded" ne me sert à rien en fait. J'ai juste vu que dans la précédente adaptation que j'avais faite, il fallait que je bind le datacontext en code-behind après que le control soit loadé, mais c'était dans le cas d'un customControl...
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 <Window ... xmlns:virtual="clr-namespace:AssetsManager.Controls.RepositoryTreeView" ... <Window.Resources> <virtual:RepositoryViewModel x:Key="Repository" XMLDocumentPath="TestRepository.xml"/> </Window.Resources> ... <TreeView DataContext="{Binding Source={StaticResource Repository}}" Loaded="TreeView_Loaded" ItemsSource="{Binding Path=RootFolders}"> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" /> <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> <Setter Property="FontWeight" Value="Normal" /> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="Foreground" Value="Black" /> </Trigger> </Style.Triggers> </Style> </TreeView.ItemContainerStyle> <TreeView.Resources> <HierarchicalDataTemplate x:Key="XMLFolders" DataType="{x:Type virtual:RepositoryFolderViewModel}" ItemsSource="{Binding Path=Children}"> <StackPanel Orientation="Horizontal"> <CheckBox Width="16" Height="16" Margin="3,0"/> <Image Width="20" Height="20" Source="/AssetsManager;component/Images/Icons/folder.ico" /> <TextBlock Text="{Binding Path=Name}" /> </StackPanel> </HierarchicalDataTemplate> </TreeView.Resources> </TreeView> ...
Voilà, j'espère qu'une (ou plusieurs) âme(s) charitable(s) pourra m'aider ! J'en ai un peu marre là de stagner depuis 3 jours
PS : désolé si j'ai écrit un pavé, j'essaie d'être le plus précis possible.
Partager