文件上传,一般会员登录网站都会有这个功能,即使没有上传文件的功能,也会有上传头像的需求,两者本质没啥区别,要说区别,可能就是一般头像比较小,不需要断点续传等功能吧。本小节介绍一下上传功能与自动完成功能。
要求选择一张图片后在上方进行预览,点击上传图片后在左侧头像处进行显示(这个页面的其它功能与信息我就没有去具体实现了)
选择图片:在sl中以类似winform中的实现,OpenFileDialog打开选择文件对话框,在返回回True时,通过File属于获取FileInfo。
上传图片:把内容转换为字符数组,通过WCF中提供的服务操作进行上传。
先看第一部分,即选择图片然后在上方的Image中把图片进行预览显示。代码可以说明一切了
OpenFileDialog fd
=
new
OpenFileDialog()
{
Filter
=
"
Jpeg Files (*.jpg)|*.jpg|All Files(*.*)|*.*
"
,
Multiselect
=
false
};
if
(fd.ShowDialog()
==
true
)
{
FileInfo fi
=
fd.File;
using
(Stream stream
=
fi.OpenRead())
{
BitmapImage image
=
new
BitmapImage();
image.SetSource(stream);
this
.imgPreview.DataContext
=
image;
this
.btnUpload.DataContext
=
fi;
stream.Close();
}
}
因为Image控件做了绑定,因此只要设置它的DataContext就可以了,而上传按钮的DataContext我是为了暂存图片,以便上传时可以直接使用,当然也可以有其它办法,我这就是随便找了个地方,呵呵
上传
FileInfo fi
=
this
.btnUpload.DataContext
as
FileInfo;
Stream stream
=
fi.OpenRead();
byte
[] fileData
=
new
byte
[stream.Length];
stream.Read(fileData,
0
, (
int
)stream.Length);
client.ActionUploadAsync(fi.Name, fileData,
false
, fi);
这里使用了第三个参数,该参数的设置可以在回调函数中使用,这是WCF代理类生成过程中自动提供的一个重载方法,很好用,如果有需要上传大文件时,可以用它来在多次的WCF调用中共享数据源。
在回调方法中
if
(e.Error
==
null
)
{
MessageBox.Show(
"
上传完成
"
);
UserInfo ui
=
this
.BorderUserInfo.Child
as
UserInfo;
ui.SetAvatars((e.UserState
as
FileInfo).Name);
}
简单处理,ui就是我左上角的用户头像部分。
再看看WCF中的实现
public
void
ActionUpload(
string
fileName,
byte
[] fileData,
bool
isAppend)
{
//
文件上传所在目录
//
可以按日期、文件类型或混合建立相应的文件目录,以便使用
string
uploadFolder
=
System.Web.Hosting.HostingEnvironment.MapPath(
"
~/upload
"
);
//
目录不存在则新建
if
(
!
System.IO.Directory.Exists(uploadFolder))
{
System.IO.Directory.CreateDirectory(uploadFolder);
}
//
文件读写模式
//
如果参数为真则表示续传,以追回模式写文件
System.IO.FileMode fileMode
=
isAppend
?
System.IO.FileMode.Append : System.IO.FileMode.Create;
//
写入文件
using
(System.IO.FileStream fs
=
new
System.IO.FileStream(uploadFolder
+
@"
\
"
+
fileName, fileMode, System.IO.FileAccess.Write))
{
fs.Write(fileData,
0
, fileData.Length);
}
}
其实这个方法是在网上找的,我只是拿来直接用了,代码很好理解,不用多做解释了。
自动完成功能的实现

使用tookit中的AutoCompleteBox控件,绑定和原来一样,设置itemsource就行了,另外注意一下FilterMode属性,代码如
client.GetAllFundCompleted
+=
new
EventHandler
<
GetAllFundCompletedEventArgs
>
(
(sender, e)
=>
{
this
.acbMainSearch.ItemsSource
=
e.Result;
this
.acbMainSearch.FilterMode
=
AutoCompleteFilterMode.Custom;
this
.acbMainSearch.ItemFilter
=
(search, item)
=>
{
WcfService.JJZB jjzb
=
item
as
WcfService.JJZB;
if
(jjzb
!=
null
)
{
return
jjzb.BZDM.StartsWith(search)
||
jjzb.Jjjc.StartsWith(search)
||
jjzb.GPjcpy.StartsWith(search.ToUpper());
}
return
false
;
};
});
client.GetAllFundAsync();
这里主要是样式的实现,根据demo中的示例,需要一个DataGridSelectionAdapter,从demo中考出来即可,说明可以参考其中的注释,使用上xaml中模板的关键代码如
这节中的功能比较简单,也没有太多需要说明的地方,都在代码中了,呵呵。