פקד checked treeview בwpf
-
אני מחפש פקד checktreeview עבור wpf אשמח אם מישהו מכיר משהו מוכן זה מאוד יעזור
בכל אופן לבינתיים ניסיתי לעשות זאת בעצמי
להוסיף את checkbox היה די קל אבל מאוד מקשה עלי העובדה שאין לי גישה ישירה בין ה- checkbox ל- treeview רק על ידי כל מיני פקודות שמחפשים את הchild של הtreeview item או רת הparent של הcheckbox
אם מישהו יודע איך עושים את זה אשמח לקבל הדרכה. תודה
הנה הקוד שיש לי לבינתיים<UserControl.Resources> <Style TargetType="CheckBox"> <EventSetter Event="Checked" Handler="CheckBox_Checked"/> <EventSetter Event="Unchecked" Handler="CheckBox_Unchecked"/> </Style> <Style TargetType="TreeViewItem"> <Setter Property="HeaderTemplate"> <Setter.Value> <DataTemplate> <StackPanel Orientation="Horizontal"> <CheckBox x:Name="checkBox"/> <TextBox Text="{Binding Path=Header, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}" BorderBrush="Transparent" Background="Transparent"/> </StackPanel> </DataTemplate> </Setter.Value> </Setter> </Style> </UserControl.Resources>
-
@dovid
אין לי מבנה אני בונה אותו מתוך תיקיותpublic static void PopulateTreeView(TreeView treeView, string booksDirectory, bool isMyBooks) { Z_SourceFolder z_SourceFolder = new Z_SourceFolder(); if (Directory.Exists(booksDirectory)) { DirectoryInfo rootDirectory = new DirectoryInfo(booksDirectory); CreateTreeView(rootDirectory, treeView, isMyBooks); } } static void CreateTreeView(DirectoryInfo directory, ItemsControl parentItem, bool isMyBooks) { foreach (var subDirectory in directory.GetDirectories()) { TreeViewItem subItem = CreateDirectoryItem(subDirectory, isMyBooks); parentItem.Items.Add(subItem); CreateTreeView(subDirectory, subItem, isMyBooks);// Recursively populate for subdirectories } foreach (var file in directory.GetFiles()) { TreeViewItem fileItem = CreateFileItem(file, isMyBooks); parentItem.Items.Add(fileItem); } } static TreeViewItem CreateDirectoryItem(DirectoryInfo directory, bool isMyBooks) { string name = Z_TranslatorClass.TranslateFolderName(directory.Name); name = Regex.Replace(name, "[0-9]+|_", ""); TreeViewItem item = new TreeViewItem(); if (isMyBooks == true) { item.Foreground = System.Windows.Media.Brushes.Firebrick; } item.Header = "🗀 " + name; item.Tag = directory.FullName; return item; } static TreeViewItem CreateFileItem(FileInfo file, bool isMyBooks) { string name = file.Name.Replace(".txt", ""); if (file.FullName.Contains("ToratEmetInstall")) { name = Z_TranslatorClass.TranslateFilename(file.FullName); } name = Regex.Replace(name, "[0-9]+|_", ""); TreeViewItem item = new TreeViewItem(); if (isMyBooks == true) { item.Foreground = System.Windows.Media.Brushes.Firebrick; } item.Header = "📑 " + name; item.Tag = file.FullName; return item; }
-
בניגוד לWinFroms בה הדרך להציג ויזואל מסויים הוא כתיבת קוד לוגי,
WPF בנויה להפרדה מוחלטת בין הנתונים והקוד (הפרוצדורלי) לבין התצוגה (שבנויה בעיקר בהצהרות XAML).
בWPF לא אמורים לכתוב בקוד צבע וכדומה.כיון שלא לגמרי הבנתי את הנושא יכול להיות שהקוד שאני מציע לא מתאים לגמרי, תשתמש בו ותשנה אותו לפי הצרכים. קודם כל בניית העץ:
public class EntryItem { public string FullName { get; protected set; } public string Name { get; protected set; } public bool IsMyBook { get; protected set; } public bool IsDirectory { get; protected set; } public bool IsChecked { get; set; } } class DirectoryItem : EntryItem { private DirectoryItem(string fullName, bool isMyBook) { FullName = fullName; var name = System.IO.Path.GetFileNameWithoutExtension(fullName); Name = Z_TranslatorClass.TranslateFolderName(name); IsMyBook = isMyBook; Entries = new List<EntryItem>(); IsDirectory = true; } public List<EntryItem> Entries { get; private set; } public static DirectoryItem CreateTree(string dirPath, bool isMyBook) { var dir = new DirectoryItem(dirPath, isMyBook); foreach (var element in Directory.GetDirectories(dirPath)) dir.Entries.Add(CreateTree(element, isMyBook)); foreach (var element in Directory.GetFiles(dirPath)) dir.Entries.Add(new FileItem(element, isMyBook)); return dir; } } public class FileItem : EntryItem { public FileItem(string fullName, bool isMyBook) { FullName = fullName; Name = System.IO.Path.GetFileNameWithoutExtension(fullName); if (FullName.Contains("ToratEmetInstall")) Name = Z_TranslatorClass.TranslateFilename(FullName); IsMyBook = isMyBook; } }
השמת המודל בTreeView:
var root = DirectoryItem.CreateTree(@"D:\Bla\Bla\", true).Entries; tv.ItemsSource = root;
והתבנית התצוגתית:
<TreeView Name="tv" HorizontalAlignment="Left" VerticalAlignment="Stretch" Width="500"> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Entries}"> <StackPanel Orientation="Horizontal"> <CheckBox IsChecked="{Binding IsChecked}" /> <TextBlock Visibility="Collapsed" Name="icon">🗀</TextBlock> <TextBlock Text="{Binding Name}" Name="text" /> </StackPanel> <HierarchicalDataTemplate.Triggers> <DataTrigger Binding="{Binding IsChecked}" Value="True" > <Setter TargetName="text" Property="Foreground" Value="Firebrick" /> </DataTrigger> <DataTrigger Binding="{Binding IsDirectory}" Value="True" > <Setter TargetName="icon" Property="Visibility" Value="Visible" /> </DataTrigger> </HierarchicalDataTemplate.Triggers> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView>
כעת בעת לחיצה על הCheckBox הערך של הIsChecked משתנה, ותוכל לאסוף את הנתונים הללו מהמודל ולא צריך לעקוב אחרי מצבו של הפקד.
בגדול, כל העסק בWPF צריך להיות על דרך זו, הפרדה ואיגוד (Binding) בין התצוגה לקוד ולא להיפך - הקוד לא אמור להכיר על הButton וכולי.