[图文并茂]WPF边学边做,图片流览器(二)

本此内容

本文首先介绍了该程序所能用到的WPF容器,然后布局界面提取图片。最后展示成果和提出下一步将要研究的问题。

1 WPF容器

2 布局界面

3 取文件夹图片

4 成果展示

5 总结和提问

1 WPF容器

容器是装对象的东西,本次讲解一类型可以排列对象的容器。WPF的Panel可以用来排列对象,我们把对象放入其中,WPF就能自动为之排列位置。System.Windows.Control.Panel是一个抽象类,所以我们不能直接使用<Panel/>的Xaml格式。其中Panel.Children是一个UIElementCollection,包含需要排列的各Item。Panel有不少派生类,我们可以使用这些Panel的派生类达到想要的排列效果。

StackPanel:Panel表示按照横向或纵向从左到右或从右到左的排列Item:任何Item都有一个排列的方式,如果没有特别指定,一般来说就是StackPanel的从上到下的压缩排列方式。若Item的长宽没有特别指定,则每个Item的高度将尽量的小,宽度将尽量的大,以占满整个Stack的宽度。若此时Stack的高度没有指定,则将尽量压缩。

WrapPanel:Panel排列Item从左到右,排列满了,然后换行,继续这样排列。WrapPanel可以根据Panel的宽度自动排列Item。

Grid:Panel是一种表格,功能强大。首先需要使用Grid.ColumnDefinitions, Grid.RowDefinitions定义表格的列属性和行属性。然后对其中的Item使用Grid.Row, Grid.Column定义其在该Grid中的第几行第几列,数值从0开始,即0行0列,就是实际上的1行1列。如果不指定几行几列则默认0行0列。下面是示例:

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image Source="Images\1.jpg"/>
<Image Grid.Column="1" Source="Images\1.jpg"/>
<Image Grid.Row="1" Source="Images\1.jpg"/>
<Image Grid.Row="1" Grid.Column="1" Source="Images\1.jpg"/>
</Grid>

效果如下,一个田字格,如果没有设置行列则4张图将重叠在一起。

2 布局界面

我们使用Gird布局,上部是一个Button,此Button取得图片文件,然后显示在下部。下部使用WrapPanel。就像这样

代码如下:

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button>取图片</Button>
<WrapPanel Grid.Row="1" ItemHeight="50" ItemWidth="50">
<Image Source="Images\1.jpg"/>
<Image Source="Images\2.jpg"/>
<Image Source="Images\3.jpg"/>
<Image Source="Images\4.jpg"/>
</WrapPanel>
</Grid>

Note

  1.  WrapPanel设置了ItemHeightItemWidth,如果不设置此2值,WrapPanel中的Item就会尽量扩大填满整个Panel,那时候你只能看到第1张图片了。
  2.  Grid的RowDefinition我设置了Height=”auto”,如果不设置则两行Gird会尽量增高,以至于高度相等。设置auto使得第1行的高度随该行内容的高度而改变,第2行会尽量增高。

3 取得一文件夹图片

流程图:

 

取文件名集合

WPF可以响应Windows消息,我们在Button中添加Click消息:

<Button Click="Buton_Click1">取图片</Button>
产生事件处理函数:
void Button_Click1(object sender,RoutedEventArgs e){…}

使用FolderBrowserDialog选择文件夹。需要注意的是WPF并不提供此对话框。我们使用System.Windows.Forms中的组件。在使用之前做下面两件事情:

  1. 对此工程添加System.Windows.Forms引用
  2. 在用到的cs文件头写上using System.Windows.Forms

首先取得文件夹下的所有文件名,并剔除非图像文件。

var fileList = Directory.EnumerateFiles ( folderName );
string[ ] tokenList = { ".jpg", ".png", ".bmp", ".jpeg", "gif" };
var imageList = fileList.Where ( x => tokenList.Any ( x1 => x.EndsWith ( x1, StringComparison.InvariantCultureIgnoreCase ) ) );
var images1 = imageList.Select ( x => new Image { Source = new BitmapImage ( new Uri ( x ) ) } );
return images1.ToList ( );

Image类System.Windows.Controls空间中,在Xaml中表示为<Image>标签。然后我们把产生的Image加入Panel中。使用Panel.Children.Add方法。

internal void AddRange(IAddChild panel, IEnumerable itemList)
{
foreach (var item in itemList)
{
panel.AddChild(item);
}
}

响应按钮事件中添加此代码,用以显示图片组:

在Xaml中<WrapPanel Name="wrapPanel1">,然后程序会实例一个wrapPanel1供开发者使用。

void Button_Click1 ( object sender, RoutedEventArgs e )
{
FolderBrowserDialog dlg = new FolderBrowserDialog ( );
if ( dlg.ShowDialog ( ) == System.Windows.Forms.DialogResult.OK )
{
var imgs = new ImageGetter().GetList(dlg.SelectedPath);
wrapPanel1.Children.Clear();
new PanelManage().AddRange(wrapPanel1,imgs);
}
}

4 成果展示

图片的文件夹显示功能就完成了。

5 总结和提问

现在我们已经可以做出程序原型了。下一步我们将进行一些优化,并介绍新的控件。

PS1:其实此程序有两个隐患,大家拿回去编码运行试试。看能发现和修正不?

PS2:这也是我将进行优化的原因

 

 

posted on 2012-04-04 14:58  甘木  阅读(4016)  评论(5编辑  收藏  举报

导航