ПОмогите начинающему, проблема с отображением иконок файлов

WPF
  1. 4 года назад

    Всем привет, только начал въезжать в WPF, дали задание, по сути нет ничего сложного проводник сделать, ну и про бы к файлам были иконки подтянуты ассоциацией с ВИнды.
    Иконки выдрал все нормально, но вот завис на проблеме, вместо нарисованной иконки, у меня везде надпись "значек". кручу верчу ничего понять не могу.. гдето что то не так а вот где, может кто сталкивался и подскажет...
    вот код
    (XAML)

    <Window x:Class="Wpf_78_.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            
            Title="MainWindow" Height="350" Width="525"
            xmlns:ds="clr-namespace:Wpf_78_">
        <Window.Resources >
            <ObjectDataProvider x:Key="FileInfoDataSource" 
                                ObjectType="{x:Type ds:MyFileInfo}">
            </ObjectDataProvider>
        </Window.Resources>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"></ColumnDefinition>
                <ColumnDefinition Width="2*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <TreeView Grid.Column="0" Name="TreeViewDisc"></TreeView>
                <ListView  Grid.Column="1" ItemsSource="{Binding Source={StaticResource FileInfoDataSource}}" Name="ListFile">
                </ListView>
        </Grid>
    </Window>

    а вот C# (где я получаю список иконок для каждого файла)

     try
                {
    
                    TreeViewItem item = ((TreeViewItem)sender);
                    if (item.Equals(TreeViewDisc.SelectedItem))
                    {
                        if (item.Items.Count >= 1)
                        {   
                            //ListFile.Items.Clear();
                            ListView myLView = new ListView();
                            GridView myGView = new GridView();
    
                            GridViewColumn gvc1 = new GridViewColumn();
                            gvc1.DisplayMemberBinding = new Binding("b");
                            gvc1.Header = "Ico";
                            gvc1.Width = 50;
                            myGView.Columns.Add(gvc1);
                            
    
                            GridViewColumn gvc2 = new GridViewColumn();
                            gvc2.DisplayMemberBinding = new Binding("FileName");
                            gvc2.Header = "FileName";
                            gvc2.Width = 50;
                            myGView.Columns.Add(gvc2);
    
                            MyFileInfo mfInfo= new MyFileInfo();
                           
                            foreach (String fNAme in Directory.GetFiles(item.Tag.ToString()))
                            {
                                System.Drawing.Icon icon=(System.Drawing.Icon)System.Drawing.Icon.ExtractAssociatedIcon(fNAme);
                                mfInfo.SetfInfo(icon, fNAme.Substring(fNAme.LastIndexOf("\\") + 1));
                            }
                            
                            ListFile.ItemsSource = mfInfo;
                            ListFile.View = myGView;
                            //myLView.ItemsSource = mfInfo;
                            //myLView.View = myGView;
                            //myStackPanel.Children.Add(myLView);
                        }
                    }
                }
                catch (Exception)
                { }
  2. Alexandr_Erohin

    Jun 26 Администратор
    Добавлено 4 года назад Alexandr_Erohin

    Структура класса данных MyFileInfo где? Тип свойства b которое биндится к gvc1 System.Drawing.Icon? В любом случае вы иконку не получите, т.к. столбцы GridView по умолчанию отображают строковые данные, нужно изменить шаблон данных как описано в статье "Шаблоны ячеек ListView" и использовать элемент Image:

    <GridViewColumn Header="Картинка">
             <GridViewColumn.CellTemplate>
                   <DataTemplate>
                          <Image Source="{Binding Path=b}"></Image>
                   </DataTemplate>
             </GridViewColumn.CellTemplate>
    </GridViewColumn>

    Свойство Source должно получать объект ImageSource а не Icon. Мой пример решения:

    Расширяющий метод объекта Icon (для преобразования Icon к ImageSource):

    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Interop;
    using System.Runtime.InteropServices;
    
    namespace WpfApplication1
    {
        internal static class IconUtilities
        {
            [DllImport("gdi32.dll", SetLastError = true)]
            private static extern bool DeleteObject(IntPtr hObject);
    
            public static ImageSource ToImageSource(this Icon icon)
            {
                Bitmap bitmap = icon.ToBitmap();
                IntPtr hBitmap = bitmap.GetHbitmap();
    
                ImageSource wpfBitmap = Imaging.CreateBitmapSourceFromHBitmap(
                    hBitmap,
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
    
                if (!DeleteObject(hBitmap))
                {
                    throw new Win32Exception();
                }
    
                return wpfBitmap;
            }
        }
    }

    Само решение WPF:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" x:Name="Window" >
        <ListView Name="ListView_Files" Margin="5">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Иконка">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <Image Source="{Binding Path=FileIcon}"></Image>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Header="Файл" DisplayMemberBinding="{Binding Path=FileName}" ></GridViewColumn>
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
    </Window>
    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Media;
    using System.IO;
    
    namespace WpfApplication1
    {
        // Класс данных
        public class MyFileInfo
        {
            public ImageSource FileIcon { get; set; }
            public string FileName { get; set; }
        }
    
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                List<MyFileInfo> files = new List<MyFileInfo>();
    
                foreach (string fileName in Directory.GetFiles(@"C:\"))
                {
                    System.Drawing.Icon icon = 
                        (System.Drawing.Icon)System.Drawing.Icon.ExtractAssociatedIcon(fileName);
    
                    files.Add(
                        new MyFileInfo
                        {
                            FileName = fileName,
                            FileIcon = icon.ToImageSource()
                        });
                }
    
                ListView_Files.ItemsSource = files;
            }
    
        }
    }

    Результат:

    -image-

  3. спасибо большое, вот теперь понятно, а за рабочий пример отдельное спасибо )

или зарегистрируйтесь чтобы ответить