none
Metro C#+XAML 点击缩略图 图片放大 再点击缩小 RRS feed

  • 问题

  • 读取电脑目录的的图片后   点击GridView里的缩略图 图片放大  再点击缩小     怎么根据缩略图 来显示原图

    MainPage

    private const uint IMAGESIZE = 1000;
            async private void btnOpen_Click(object sender, RoutedEventArgs e)
            {
                ObservableCollection<ImageItem> imageItemList = new ObservableCollection<ImageItem>();
                FileOpenPicker openPicker = new FileOpenPicker();
                openPicker.ViewMode = PickerViewMode.Thumbnail;
                openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
                openPicker.FileTypeFilter.Add(".jpg");
                openPicker.FileTypeFilter.Add(".gif");
                openPicker.FileTypeFilter.Add(".png");
                openPicker.FileTypeFilter.Add(".bmp");

                var fileList = await openPicker.PickMultipleFilesAsync();
            
                if (fileList.Count > 0)
                {
                    foreach (var item in fileList)
                    {
                        Object imgName = item.Name;
                      
                        using (StorageItemThumbnail thumbnail = await item.GetThumbnailAsync(ThumbnailMode.PicturesView, IMAGESIZE, ThumbnailOptions.ResizeThumbnail))
                        {
                            if (null != thumbnail)
                            {
                                ImageItem imageItem = new ImageItem();
                                imageItem.Image.SetSource(thumbnail);
                                imageItemList.Add(imageItem);
                            }
                        }
                        Object[] imageList = new Object[] { imageItemList, imgName };
                        this.Frame.Navigate(typeof(Show), imageList);
                    }
                }
                //跨页传输数据
                //this.Frame.Navigate(typeof(Show),imageItemList);
            }

            public class ImageItem : INotifyPropertyChanged
            {
                public event PropertyChangedEventHandler PropertyChanged;

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

                private BitmapImage _Image = new BitmapImage();

                public BitmapImage Image
                {
                    get
                    {
                        return _Image;
                    }
                    set
                    {
                        if (_Image != value)
                        {
                            _Image = value; this.OnPropertyChanged("Image");
                        }
                    }
                }

                public void SetImage(String path)
                {
                    Image = new BitmapImage(new Uri(path));
                }
            }

        }

    Show.XAML

     <Viewbox x:Name="viewBox"   HorizontalAlignment="Left"  Width="1366" Margin="0,0,0,-52"  Grid.RowSpan="2" SizeChanged="viewBox_SizeChanged">
                <GridView x:Name="gvShow" BorderThickness="10" BorderBrush="Black" HorizontalAlignment="Left" Grid.Row="1"  Width="1366" Margin="0,5,0,0" Height="708" SelectionMode="None">
                    <GridView.ItemTemplate>
                        <DataTemplate>
                            <Grid >
                                <!--<ScrollViewer x:Name="scrollViewer"  BorderThickness="0"   HorizontalAlignment="Center" ZoomMode="Enabled" MaxZoomFactor="20" HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">-->
                                <StackPanel>
                                    <Image x:Name="imgSm" Width="400"  HorizontalAlignment="Left" Grid.Row="1"  Source="{Binding Image}" Stretch="UniformToFill"  Tapped="imgSm_Tapped" />
                                </StackPanel>
                                <!--</ScrollViewer>-->
                            </Grid>
                        </DataTemplate>
                    </GridView.ItemTemplate>
                </GridView>
            </Viewbox>

    • 已更改类型 Mr Lou 2012年7月6日 3:14 Metro
    • 已移动 Jason Dot Wang 2012年7月9日 7:38 这个帖子是关于Metro风格的应用开发 (发件人:Visual C#)
    2012年7月6日 2:54

答案

  • 所以我这里需要提到你的 绑定的数据对象,你应该建立一个数据model 类型,里面有两个属性去分别存放缩略图和原图,最好还可以有属性是控制空间显示和隐藏的。然后你需要构建这个数据模型的集合并且绑定到GridView的ItemsSource上,DataTemplate的Image上分别绑定其数据模型的属性,Visiblity属性也可以进行绑定到显示隐藏的属性上。 你在Image 的点击事件中你可以通过 (sender as Image).DataContext as datamodel;  来获得这个点击项所对应的绑定数据模型对象,然后改变其属性就可以控制显示和隐藏。

    这里其实就是贯彻一个理念  "数据驱动UI",类型理念体现在MVVM模式中,你可以参考一些Silverlight WPF的设计,通常都会使用这种模式。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 Mr Lou 2012年7月10日 1:08
    2012年7月9日 9:52
    版主

全部回复

  • Hi _____L.Y.H先生,

      欢迎来到MSDN论坛。

      我已经告知精通这个开发技术的工程师了,如果他有满意的解决方案,你能及时得到相关的回复。

     


    Jason Wang [MSFT]
    MSDN Community Support | Feedback to us

    2012年7月9日 7:48
  • 我的建议是使用语义缩放 (Quickstart)dView, 参考语义缩放例子:http://code.msdn.microsoft.com/windowsapps/GroupedGridView-77c59e8e 

    如果不是这样的话,你也可以在数据模板中放置两个Image,点击的时候切换其显示和隐藏的状态。 然后你的数据中需要有两个Image属性分别半寸缩略图和原图,用于这两个Images控件的绑定。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年7月9日 7:59
    版主
  • 你好  你的意思是放两个image 控件 我已经放了两个Image控件   。还有一个问题?   当点击GridVIew 里的缩略图时(Image1(缩略图)) 怎么获取缩略图的的Name  然后通过Name   实现当显示Image2(原图)时  当前显示是点击的缩略图的原图  


    _____L.Y.H先生


    • 已编辑 Mr Lou 2012年7月9日 8:39
    2012年7月9日 8:38
  • 所以我这里需要提到你的 绑定的数据对象,你应该建立一个数据model 类型,里面有两个属性去分别存放缩略图和原图,最好还可以有属性是控制空间显示和隐藏的。然后你需要构建这个数据模型的集合并且绑定到GridView的ItemsSource上,DataTemplate的Image上分别绑定其数据模型的属性,Visiblity属性也可以进行绑定到显示隐藏的属性上。 你在Image 的点击事件中你可以通过 (sender as Image).DataContext as datamodel;  来获得这个点击项所对应的绑定数据模型对象,然后改变其属性就可以控制显示和隐藏。

    这里其实就是贯彻一个理念  "数据驱动UI",类型理念体现在MVVM模式中,你可以参考一些Silverlight WPF的设计,通常都会使用这种模式。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 Mr Lou 2012年7月10日 1:08
    2012年7月9日 9:52
    版主
  • 你好  Moldel 类型我建了   但是Metro里怎么通过缩略图定位与他对应的原图  Metro里没有FileInfo     求教


    _____L.Y.H先生

    2012年7月11日 3:12
  • 你在创建一个Model对象对于一张图片的时候就可以将原图设置到Model对象上,或者将图像的访问信息放置上去。

    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年7月11日 3:34
    版主
  • 我是直接用 FileOpenPicker  打开的  没有具体的图片路径

    _____L.Y.H先生


    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Navigation;
    using Windows.Storage.Pickers;
    using Windows.Storage;
    using Windows.Storage.Streams;
    using Windows.UI.Xaml.Media.Imaging;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using Windows.ApplicationModel.Resources.Core;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Media;
    using Windows.Storage.FileProperties;


    namespace ShowImage.Model
    {
        public class ImageItem : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;

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

            //缩略图
            private BitmapImage _ImageSmall = new BitmapImage();
            public BitmapImage ImageSmall
            {
                get
                {
                    return _ImageSmall;
                }
                set
                {
                    if (_ImageSmall != value)
                    {
                        _ImageSmall = value; this.OnPropertyChanged("ImageSmall");
                    }
                }
            }

            //原图
            private BitmapImage _ImageBig = new BitmapImage();
            public BitmapImage ImageBig
            {
                get
                {
                    return _ImageBig;
                }
                set
                {
                    if (_ImageBig != value)
                    {
                        _ImageBig = value; this.OnPropertyChanged("ImageBig");
                    }
                }
            }

            //缩略图
            public void SetImageSmall(String path)
            {
                ImageSmall = new BitmapImage(new Uri(path));
            }

            //原图
            public void SetImageBig(String path)
            {
                ImageBig = new BitmapImage(new Uri(path));
            }

        }
    }

    • 已编辑 Mr Lou 2012年7月11日 5:18
    2012年7月11日 5:16
  • 那你在打开图片的时候就构建这个 ImageItem ,直接将ImageBig 都构建好,不要等到之后构建。通过Stream读入创建 BitmapImage。

    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年7月11日 5:44
    版主
  • 你好 看下我的代码  现在改变下需求 当点击GridView里的缩略图时 将原图的集合 传值到 新的页面 并用FlipView来显示(并且当前显示的是点击缩略图的原图)   可是遇到了问题 在Tapped事件中读取不到imageItemListBig       或者可以在Open方法中用Navigate  只传值不跳转   但不知道怎么实现

    private const uint IMAGESIZE = 400;
            async private void Open()
            {
                ObservableCollection<ImageItem> imageItemListBig = new ObservableCollection<ImageItem>();
                ObservableCollection<ImageItem> imageItemListSmall = new ObservableCollection<ImageItem>();
                FileOpenPicker openPicker = new FileOpenPicker();
                openPicker.ViewMode = PickerViewMode.Thumbnail;
                openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
                openPicker.FileTypeFilter.Add(".jpg");
                openPicker.FileTypeFilter.Add(".gif");
                openPicker.FileTypeFilter.Add(".png");
                openPicker.FileTypeFilter.Add(".bmp");

                var fileList = await openPicker.PickMultipleFilesAsync();

                BitmapImage bitmapImage = new BitmapImage();
                StorageFile storageFile = await openPicker.PickSingleFileAsync();

                if (fileList.Count > 0)
                {
                    foreach (var item in fileList)
                    {


                        //原图
                        IRandomAccessStream randomAccessStream = await item.OpenReadAsync();
                        ImageItem imageItemBig = new ImageItem();
                        imageItemBig.ImageBig.SetSource(randomAccessStream);
                        imageItemListBig.Add(imageItemBig);

                        //using (IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read))
                        //{
                        //    bitmapImage.SetSource(stream);
                        //}

                        //缩略图
                        using (StorageItemThumbnail thumbnail = await item.GetThumbnailAsync(ThumbnailMode.PicturesView, IMAGESIZE, ThumbnailOptions.ResizeThumbnail))
                        {
                            if (null != thumbnail)
                            {
                                ImageItem imageItemSmall = new ImageItem();
                                imageItemSmall.ImageSmall.SetSource(thumbnail);
                                imageItemListSmall.Add(imageItemSmall);
                            }
                        }    
                    }           
                }

                  gvShow.ItemsSource = imageItemListSmall;
            }


    _____L.Y.H先生

    2012年7月11日 6:57
  • 很奇怪,你为什么已经有了一个Model并且有了两个属性,Big和Small Image,还要为他们创建不同的对象和集合。

    至于你读不到imageItemListBig,是因为 imageItemListBig 是局部变量。

    不过我的想法是你只需要一个集合, ObservableCollection<ImageItem> imageItem, 然后里面的ImageItem分别都有原图和缩略图两者,你在 gvShow 的DataTemplate都做好绑定,只需要切换两个Images控件;或者你在处理 切换事件的时候,将ImageBig的属性值读出来。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年7月11日 8:03
    版主