WPF - ListView
-
החלון שאני עוסק בו כעת אמור להציג תוכן תיקיה נבחרת, התוכן כולל קבצים ותקיות משנה, ואני רוצה להציג אותו ב ListView,
עמודה הראשונה ב ListView תהיה האיקון של הקובץ או התקיה כפי שהוא מוגדר בריגיסטרי [ולזה יש לי קוד שמחלץ את האייקונים] ובשאר העמודות ב ListView אני מציג טקסט כמו שם הקובץ תאריך שינוי וכדומה.התיקיה שאותה אני רוצה להראות בתוך ה ListView משתנת כל פעם ע''י משתמש ולכן גם האיקונים צריכים להשתנות בהתאם.
תודה רבה.
<Window x:Class="Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="765"> <Grid> <ListView Margin="12,41,12,12" ItemsSource="{Binding}" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler" SelectionMode="Multiple" Foreground="Black"> <ListView.View> <GridView> <GridViewColumn Header="ico" Width="30" DisplayMemberBinding="{Binding ICON}" CellTemplate="{Binding ICON}" /> <GridViewColumn Header="שם" Width="200" /> <GridViewColumn Header="תיקיה מכילה" Width="200" /> <GridViewColumn Header="סוג" Width="70" /> <GridViewColumn Header="תאריך שינוי" Width="200" /> <GridViewColumn Header="גודל" Width="100" /> </GridView> </ListView.View> </ListView> </Grid> </Window>
פורסם במקור בפורום CODE613 ב17/10/2013 11:05 (+03:00)
-
למה לא להביא xaml?
חשוב לדעת איפה אתה אוחז.
א. יש הרבה הרבה אפשרויות להציג מידע בפקדי xaml.
ב. יש הרבה אפשרויות איך לנהל את הקוד מאחורה.
ג. לליסטויו יש אפשרויות תצוגה טבלאית ואחרות.עשיתי דוגמה בסיסית עם פירוט רב כדי שתראה את היקף ההיבטים.
קודם הXAML:<ListView ItemsSource="{Binding Source={StaticResource CollForList}}" MouseDoubleClick="listFiles_MouseDoubleClick" > <ListView.View> <GridView> <GridViewColumn > <GridViewColumn.CellTemplate> <DataTemplate> <Image Source="{Binding icon}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="שם" DisplayMemberBinding="{Binding Name}" /> <GridViewColumn Header="תאריך שינוי" DisplayMemberBinding="{Binding DateChange}" /> </GridView> </ListView.View> </ListView>
הזאמל הזה עושה שימוש בריסורס, אביא אף אותו
<Window.Resources> <CollectionViewSource x:Key="CollForList" /> </Window.Resources>
הקוד VB במקרה זה:
Private Coll As CollectionViewSource Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded Coll = Me.Resources("CollForList") ListBuilder(New IO.DirectoryInfo("c:\")) End Sub Private Sub ListBuilder(dirBase As IO.DirectoryInfo) Dim files = From file In dirBase.EnumerateFiles() Select New FileOrFolder(file) Dim directories = From dir In dirBase.EnumerateDirectories Select New FileOrFolder(dir) Coll.Source = files.Concat(directories) End Sub Private Sub listFiles_MouseDoubleClick(sender As Object, e As MouseButtonEventArgs) Dim f = TryCast(CType(e.OriginalSource, FrameworkElement).DataContext, FileOrFolder) If f IsNot Nothing Then If f.IsDir Then ListBuilder(New IO.DirectoryInfo(f.FullName)) End If End If End Sub
הקוד משתמש במחלקה זאת:
Class FileOrFolder Public FullName As String Public Property IsDir As Boolean Public Property Name As String Public Property DateChange As Date Public Property Image As ImageSource Public Sub New(file As IO.FileInfo) FullName = file.FullName Name = file.Name '.... End Sub Public Sub New(dir As IO.DirectoryInfo) IsDir = True FullName = dir.FullName Name = dir.Name '.... End Sub End Class
תשלים את הקוד החסר (איפה שיש שלוש נקודות) לפי טעמך.
יש כאן הרבה "הנחות עבודה". כל דבר שעשיתי אפשר אחרת.
אבל זה מבט מהיר לאיך שWPF מתמודד עם נתונים.פורסם במקור בפורום CODE613 ב17/10/2013 13:05 (+03:00)
-
תודה רבה,
כל זה הבנתי, אבל איפה האייקון?בקוד שלך הבאת:
<GridViewColumn.CellTemplate> <DataTemplate> <Image Source="{Binding icon}" /> </DataTemplate> </GridViewColumn.CellTemplate>
ואני עשיתי בקוד שלי אותו דבר:
<GridViewColumn Header="ico" Width="30" DisplayMemberBinding="{Binding ICON}" CellTemplate="{Binding ICON}" />
אבל האיקון לא מופיע כי לא שמנו כלום ב Public Property Image As ImageSource
בקיצור איך אני מגדיר את המאפיין הזה בזמן ריצה ?
ושוב תודה רבה.פורסם במקור בפורום CODE613 ב17/10/2013 14:45 (+03:00)
-
ציפיתי שתיקח את מה ששלחתי הלאה, לא חשבתי שגמרתי.
אתה צודק, טעיתי בכך שבחרתי את השם Image בקוד, אחרי שבXAML הפניתי לicon. צריך לשנות את אחד מהם כדי ששניהם יהיו אותו השם.כדי להציג את האייקון שלך, אני צריך לדעת איך אתה מחזיק אותו. כאייקון?
פורסם במקור בפורום CODE613 ב17/10/2013 16:47 (+03:00)
-
אני משתמש בקוד הבא כדי לקבל איקונים:
Imports System.Runtime.InteropServices Public Class SYS_ICO Public Shared ICO_DIC As New Dictionary(Of String, Icon) 'This function get the icon for the specified file path extension Public Shared Function GetIcon(ByVal filePath As String) As System.Drawing.Icon Try Dim ico As System.Drawing.Icon 'Get the extension Dim ext As String = IO.Path.GetExtension(filePath) ' בודק אם האיקון כבר קיים ICO_DIC.TryGetValue(ext, ico) If ico IsNot Nothing Then Return ico End If Dim shellFileInfo As New SYS_ICO.SHFILEINFO() SYS_ICO.SHGetFileInfo(ext, 128, shellFileInfo, _ Convert.ToUInt32(Marshal.SizeOf(shellFileInfo)), _ Convert.ToUInt32(256I Or 1I Or 16I)) ico = System.Drawing.Icon.FromHandle(shellFileInfo.hIcon) ICO_DIC.Add(ext, ico) Return ico Catch ex As Exception Return My.Resources.איקון End Try End Function <StructLayout(LayoutKind.Sequential)> _ Private Structure SHFILEINFO Public hIcon As IntPtr Public iIcon As Integer Public dwAttributes As System.UInt32 <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _ Public szDisplayName As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _ Public szTypeName As String End Structure <DllImport("Shell32.dll", ENTRYPOINT:="SHGetFileInfo")> _ Private Shared Function SHGetFileInfo( ByVal pszPath As String, ByVal dwFileAttributes As System.UInt32, ByRef psfi As SHFILEINFO, ByVal cbFileInfo As System.UInt32, ByVal uFlags As System.UInt32) As IntPtr End Function End Class
פורסם במקור בפורום CODE613 ב17/10/2013 17:55 (+03:00)
-
תחליף את תחילת הקוד, מההצהרה על הDictionary כולל, ועד סוף הפונקציה הראשונה,
בקוד דלהלן:Public Shared ICO_DIC As New Dictionary(Of String, ImageSource) 'This function get the icon for the specified file path extension Public Shared Function GetIcon(ByVal filePath As String) As ImageSource Try Dim wpfBitmap As ImageSource 'Get the extension Dim ext As String = IO.Path.GetExtension(filePath) ' בודק אם האיקון כבר קיים ICO_DIC.TryGetValue(ext, wpfBitmap) If wpfBitmap IsNot Nothing Then Return wpfBitmap End If Dim shellFileInfo As New SYS_ICO.SHFILEINFO() SYS_ICO.SHGetFileInfo(ext, 128, shellFileInfo, _ Convert.ToUInt32(Marshal.SizeOf(shellFileInfo)), _ Convert.ToUInt32(256I Or 1I Or 16I)) Dim ico As System.Drawing.Icon = System.Drawing.Icon.FromHandle(shellFileInfo.hIcon) wpfBitmap = FromIconToImageSource(ico) ICO_DIC.Add(ext, wpfBitmap) Return wpfBitmap Catch ex As Exception Return FromIconToImageSource(My.Resources.איקון) End Try End Function Private Shared Function FromIconToImageSource(icon As System.Drawing.Icon) As ImageSource Dim bitmap As System.Drawing.Bitmap = icon.ToBitmap() Dim hBitmap As IntPtr = bitmap.GetHbitmap() Dim wpfBitmap As ImageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()) Return wpfBitmap End Function
ואח"כ אתה שם את התוצאה במאפיין הImageSource של המחלקה דלעיל.
פורסם במקור בפורום CODE613 ב17/10/2013 19:47 (+03:00)
-
יפה מאוד, תודה רבה יישר כח!
@דוד ל.ט.
מעניין אותי איך הצלחת להכניס ערכים טקסטואליים בכל העמודות (שם, גודל וכו') ?
מה שעושים ב XAML עשיתי בקוד של הבנאי:
אתה נותן שם לכל עמודה בליסט-ויושם_עמודה.DisplayMemberBinding = New Binding("שם_המאפיין")
פורסם במקור בפורום CODE613 ב17/10/2013 20:34 (+03:00)
-
זה ממש נפלא כעת! האיקונים מוסיפים המון.
רק הבעיה שהם לא חדים אע''פ שהם מוצגים ברזולוציה המקורית שלהם, אותו דבר ב WINFORMS היא נראה יותר חד, יש מה לעשות עם זה?מעניין. תנסה סתם תמונה אחרת.
@דוד ל.ט.
מעניין אותי איך הצלחת להכניס ערכים טקסטואליים בכל העמודות (שם, גודל וכו') ?מה שעושים ב XAML עשיתי בקוד של הבנאי:
אתה נותן שם לכל עמודה בליסט-ויושם_עמודה.DisplayMemberBinding = New Binding("שם_המאפיין")
הבעיה שהקוד שלך לא הכיל בכלל שם לעמודות וגם לא לטבלה כולה לכן התפלאתי.
פורסם במקור בפורום CODE613 ב11/11/2013 15:18 (+02:00)