解决位图缩略图的问题

时间:2013-11-27 00:19:18

标签: c# wpf binding bitmap .net

徘徊如果我可以得到帮助,组合框列出hdds,点击时我希望列表框列出来自该相应硬盘的位图图像缩略图(每个选定的硬盘转换为字符串,我希望用作获取的地址缩略图,我最初帮助让这个只用完整的图像,但因为那很慢我正在尝试使用缩略图,到目前为止,我没有错误,但列表框中没有任何显示,我确定我已经绑定了

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e) //Window Loaded Event
    {
        ///Load Avaliable Drives Into ComboBox
        string[] drives = Environment.GetLogicalDrives(); //Drive Letters, Into A String Array

        foreach (string drive in drives)
        {
            HDDSelectionBox.Items.Add(drive); //Adds Each Drive Letter As A Combox Box Item
        }


        string root = (HDDSelectionBox.SelectedItem.ToString()); //Contains Directory Path For Images
        string[] supportedExtensions = new[] { ".bmp", ".jpeg", ".jpg", ".png", ".tiff" };
        var files = System.IO.Directory.EnumerateFiles(root, "*.*").Where(s => supportedExtensions.Contains(System.IO.Path.GetExtension(s).ToLower()));

        List<Photos> images = new List<Photos>();
        if (HDDSelectionBox.SelectedItem != null) //If a item has been selected
        {
        foreach (var file in files)
            {
                Photos id = new Photos()
                {
                    Path = file,
                    FileName = System.IO.Path.GetFileName(file),
                    Extension = System.IO.Path.GetExtension(file)
                };

                BitmapImage img = new BitmapImage();
                img.BeginInit();
                img.CacheOption = BitmapCacheOption.OnLoad;
                img.UriSource = new Uri(file, UriKind.Absolute);
                img.EndInit();
                id.Width = img.PixelWidth;
                id.Height = img.PixelHeight;

                // I couldn't find file size in BitmapImage
                FileInfo fi = new FileInfo(file);
                id.Size = fi.Length;
                images.Add(id);
            }

            ImageListBox.ItemsSource = images;
        }
    }

}


public class Photos
{
    /// <summary>
    /// A name for the image, not the file name.
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// A description for the image.
    /// </summary>
    public string Description { get; set; }

    /// <summary>
    /// Full path such as c:\path\to\image.png
    /// </summary>
    public string Path { get; set; }

    /// <summary>
    /// The image file name such as image.png
    /// </summary>
    public string FileName { get; set; }

    /// <summary>
    /// The file name extension: bmp, gif, jpg, png, tiff, etc...
    /// </summary>
    public string Extension { get; set; }

    /// <summary>
    /// The image height
    /// </summary>
    public int Height { get; set; }

    /// <summary>
    /// The image width.
    /// </summary>
    public int Width { get; set; }

    /// <summary>
    /// The file size of the image.
    /// </summary>
    public long Size { get; set; }

}

}

1 个答案:

答案 0 :(得分:1)

首先创建一个可用于执行属性通知的基本模型(XAML控件需要这样才能响应更改:

public abstract class ObservableObject : INotifyPropertyChanged
{
    protected ObservableObject()
    {
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpresion)
    {
        var property = (MemberExpression)propertyExpresion.Body;
        this.OnPropertyChanged(property.Member.Name);
    }

    protected void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected void SetValue<T>(ref T refValue, T newValue, Expression<Func<T>> propertyExpresion)
    {
        if (!object.Equals(refValue, newValue))
        {
            refValue = newValue;
            this.OnPropertyChanged(propertyExpresion);
        }
    }

    protected void SetValue<T>(ref T refValue, T newValue, Action valueChanged)
    {
        if (!object.Equals(refValue, newValue))
        {
            refValue = newValue;
            valueChanged();
        }
    }

    protected void SetValue<T>(ref T refValue, string propertyName, T newValue)
    {
        if (!object.Equals(refValue, newValue))
        {
            refValue = newValue;
            this.OnPropertyChanged(propertyName);
        }
    }
}

现在创建一个枚举硬盘和图像并创建缩略图的模型:

public class ImagesModel : ObservableObject
{
    private ObservableCollection<string> _HardDrives;
    public ObservableCollection<string> HardDrives
    {
        get {return this._HardDrives;}
        set {this._HardDrives = value; OnPropertyChanged(() => this.HardDrives);}
    }

    private string _CurrentDrive;
    public string CurrentDrive
    {
        get {return this._CurrentDrive;}
        set {
            this._CurrentDrive = value;
            OnPropertyChanged(() => this.CurrentDrive);

            // enumerate files in this drives
            string[] supportedExtensions = new[] { ".bmp", ".jpeg", ".jpg", ".png", ".tiff" };
            this.Images = new ObservableCollection<PhotoModel>(
                System.IO.Directory.EnumerateFiles(value, "*.*")
                .Where(s => supportedExtensions.Contains(System.IO.Path.GetExtension(s).ToLower()))
                .Select(filename => new PhotoModel(filename)));
        }
    }

    private ObservableCollection<PhotoModel> _Images;
    public ObservableCollection<PhotoModel> Images
    {
        get {return this._Images;}
        set {this._Images = value; OnPropertyChanged(() => this.Images);}
    }

    private PhotoModel _CurrentImage;
    public PhotoModel CurrentImage
    {
        get {return this._CurrentImage;}
        set {this._CurrentImage = value; OnPropertyChanged(() => this.CurrentImage);}
    }

    public ImagesModel()
    {
        this.HardDrives = new ObservableCollection<string>(Environment.GetLogicalDrives());
    }
}

public class PhotoModel : ObservableObject
{
    private string _FileName;
    public string FileName
    {
        get {return this._FileName;}
        private set { this._FileName = value; OnPropertyChanged(() => this.FileName);}
    }

    private ImageSource _Image;
    public ImageSource Image {
        get {return this._Image;}
        private set {this._Image = value;OnPropertyChanged(() => this.Image);}
    }

    public PhotoModel(string filename)
    {
        this.FileName = filename;
        BitmapImage img = new BitmapImage();
        img.BeginInit();
        img.CacheOption = BitmapCacheOption.OnLoad;
        img.UriSource = new Uri(filename, UriKind.Absolute);
        img.DecodePixelWidth = 64;  // or whatever
        img.EndInit();
        this.Image = img;
    }
}

显然,您需要创建此类的实例并将其分配给Windows的DataContext:

public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ImagesModel();
    }

最后将您的ComboBox和ListBox添加到窗口,设置绑定并覆盖ListBox项目模板以显示图像:

<Grid>
    <ComboBox ItemsSource="{Binding HardDrives}" SelectedValue="{Binding CurrentDrive}" HorizontalAlignment="Left" Margin="27,35,0,0" VerticalAlignment="Top" Width="120"/>
    <ListBox ItemsSource="{Binding Images}" SelectedValue="{Binding CurrentImage}" HorizontalAlignment="Left" Height="212" Margin="27,87,0,0" VerticalAlignment="Top" Width="188">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Image Width="64" Height="64" Source="{Binding Image}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

</Grid>