博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Asp.Net MVC2 控件开发实例(3)
阅读量:5033 次
发布时间:2019-06-12

本文共 11222 字,大约阅读时间需要 37 分钟。

 

    这次是一个图片控件,实现轮播、上传、删除、修改以及点击时放大等功能。 先来看最终效果:

   

 

 

 

 

 

 

 

 

 

 

说明:轮播的CSS参考了网上一篇文章,具体链接忘记了,其余为原创。

    书归正传。这个控件有几个功能点,1是无刷新上传和修改,这里使用了一个上传插件,详见:

。官方有使用说明,这里我就不讨论了;2是新增修改和删除图标的定位问题,CSS设置定位和层叠即可,也不细说了;3是点击小图显示大图的问题,这里面还有缩略图问题;4是控件单独刷新。以下将依次说明。

    首先构建基本的HTML和CSS:

ExpandedBlockStart.gif
HTML+CSS
<
div 
class
="banner_f"
>
    
<
div 
class
="banner"
>
        
<
div 
class
="banner_bg"
>
        
</
div
>
        
<!--
标题
-->
        
<
div 
class
="banner_info"
>
    
</
div
>
        
<!--
标题背景
-->
        
<
div 
class
="banner_list"
>
        
</
div
>
        
<
div 
class
="div_imgHD"
>
        
</
div
>
    
</
div
>
    
<
ul 
class
="banner_ul"
>
        
</
ul
>
</
div
>
<%
=
Html.Hidden(
"
ZPDTID
"
, Model.ZPDTID 
as
 
string
)
%>
<%
=
Html.Hidden(
"
PhotoYWdtid
"
, Model.PhotoYWdtid 
as
 
string
)
%>
<%
=
Html.Hidden(
"
HD_Width
"
, Model.HD_Width 
as
 
string
)
%>
<%
=
Html.Hidden(
"
HD_Height
"
, Model.HD_Height 
as
 
string
)
%>
<
style 
type
="text/css"
>
    .banner_f
    
{
        height
:
 140px
;
        width
:
 91px
;
        position
:
 relative
;
 
        border
:
 1px solid #666
;
    
}
    .banner
    
{
        position
:
 relative
;
        width
:
 90px
;
        height
:
 120px
;
        border
:
 1px solid #666
;
        overflow
:
 hidden
;
    
}
    .banner_list img
    
{
        border
:
 0px
;
        height
:
 120px
;
        width
:
 90px
;
    
}
    .banner_list
    
{
        float
:
 left
;
    
}
    .div_imgHD
    
{
        display
:
none
;
    
}
    .banner_bg
    
{
        position
:
 absolute
;
        bottom
:
 0
;
        background-color
:
 #ffffff
;
        height
:
 20px
;
        filter
:
 Alpha(Opacity=30)
;
        opacity
:
 0.3
;
        z-index
:
 1000
;
        cursor
:
 pointer
;
        width
:
 90px
;
    
}
    .banner_info
    
{
        position
:
 absolute
;
        bottom
:
 0
;
        left
:
 15px
;
        height
:
 15px
;
        color
:
 #fff
;
        z-index
:
 1001
;
        cursor
:
 pointer
;
        left
:
30%
;
    
}
    .banner_text
    
{
        position
:
 absolute
;
        width
:
 90px
;
        z-index
:
 1002
;
        right
:
 3px
;
        bottom
:
 3px
;
    
}
    .banner_ul
    
{
        position
:
 absolute
;
        list-style-type
:
 none
;
        filter
:
 Alpha(Opacity=80)
;
        opacity
:
 0.8
;
        border
:
 1px solid #fff
;
        z-index
:
 1002
;
        margin
:
 0
;
        padding
:
 0
;
        bottom
:
 0
;
        right
:
 5px
;
        height
:
 17px
;
    
}
    .banner_ul li
    
{
        padding
:
  0px 4px
;
        float
:
 left
;
        display
:
 block
;
        color
:
 #FFF
;
        border
:
 #e5eaff 1px solid
;
        background-color
:
 #6f4f67
;
        cursor
:
 pointer
;
        width
:
 3px
;
    
}
    .banner_list a
    
{
        position
:
 absolute
;
    
}

</style> 

 简单说明一下:banner_f是整个控件的外层div,高度为图片高度120+导航高度20=140,宽度为图片宽度90+border1=91,相对定位;banner为图片div;banner_list为图片div;div_imgHD为显示大图的div(初始为隐藏);banner_ul为导航。

使用的时候这样即可:

$('#tdPhoto').load('/FM/Modify/BannerPhoto', { YWDTID: dtid, timeStamp: time,width:'450',height:'600' }, function () {
         fillRYPhoto($('#ZPDTID').val() == null ? '' : $('#ZPDTID').val(), false, 0);

     }); 其中tdPhoto是需要填充此图片控件的控件ID,'/FM/Modify/BannerPhoto'为请求的action(此action作用为返回此图片控件的PartialViewResult),YWDTID是这些图片的数据源ID,timeStamp为时间戳以避免缓存问题,width为显示大图时的外围层宽度,height为大图外围层高度(或者说是想显示大图的最大宽度和高度以便自适应尺寸来保证图片不变形),回调方法fillRYPhoto填充图片。

    首先是action,作用就是绑定一些页面数据并返回PartialViewResult:

ExpandedBlockStart.gif
View Code
[HttpPost()]
        
public
 PartialViewResult BannerPhoto(
string
 YWDTID, 
string
 timeStamp,
string
 width,
string
 height)
        {
            
string
 ZPDTIDList 
=
 
string
.Empty;
            DataTable zpDt 
=
 GetZpDt(YWDTID, 
out
 ZPDTIDList);
            dynamic m 
=
 
new
 System.Dynamic.ExpandoObject();
            m.ZPDTID 
=
 ZPDTIDList;
            m.PhotoYWdtid 
=
 YWDTID;
            m.HD_Width 
=
 width;
            m.HD_Height 
=
 height;
            
return
 PartialView(
"
~/Views/Shared/BannerPhoto.ascx
"
, m);}

然后是回调方法 fillRYPhoto,由于初始的html里面只包含了外层控件,所以这里面做的事情比较多,包括所有内层控件的回填:

 

<
script type
=
"
text/javascript
"
>
    
//
#region fillRYPhoto
    
function
 fillRYPhoto(IDList, hidButton, index) {
        
if
 (index 
== 
null 
||
 index 
== 
'
undefined
'
) {
            index 
= 
0
;
        }
        $.unblockUI;
        
var
 list 
=
 IDList.toString().split(
'
,
'
);
        $(
'
.banner_ul
'
).eq(index).empty();
        $(
'
.banner_list
'
).eq(index).empty();
        
for
 (
var
 i 
= 
0
; i 
<
 list.length; i
++
) {
            $(
'
.banner_ul
'
).eq(index).append(
"
<li>
" 
+
 (i 
+ 
1
).toString() 
+ 
"
</li>
"
);
            $(
'
.banner_list
'
).eq(index).append(
"
<a href='javascript:///'><img title='点击放大' id='
"
+
 list[i] 
+ 
"
' οnclick=\"showHDimg(this.id,
"
+
index
+
"
);\" src=\"/FM/Modify/GetRyPhotoByID?ZPDTID='
" 
+
 list[i] 
+ 
"
'&timestamp=
" 
+ 
new
 Date() 
+ 
"
\"  /></a>
"
);
        }
        
if
 ($(
'
.banner_ul
'
).eq(index).children(
'
li
'
).length 
< 
2
) {
            $(
'
.banner_ul
'
).eq(index).remove();
            $(
'
.banner_f
'
).eq(index).css(
'
height
'
'
120px
'
);
        }
        
else
 {
            $(
'
.banner_ul
'
).eq(index).children(
'
li
'
).show();
        }
        bindZPClick(hidButton,index);
    }
    
//
#endregion
    
//
#region showHDimg:显示大图
    
function
 showHDimg(imgID,index) {
        
var
 selector 
= 
'
.banner_list:eq(
' 
+
 index 
+ 
'
)
' 
+ 
'
 img
'
;
        
if
 ($(selector).attr(
'
id
'
).length 
== 
0
) { 
return
 };
        
var
 hd_width 
=
 $(
'
#HD_Width
'
).val();
        
var
 hd_height 
=
 $(
'
#HD_Height
'
).val();
        $(
'
.div_imgHD
'
).eq(index).empty().append(
"
<img id='
" 
+
 imgID 
+ 
"
_HD'
" 
+ 
"
 src=\"/FM/Modify/GetRyPhotoHDByID?ZPDTID='
" 
+
 imgID 
+ 
"
'&hd_width=
" 
+
 hd_width 
+ 
"
&hd_height=
" 
+
 hd_height 
+ 
"
&timestamp=
" 
+ 
new
 Date() 
+ 
"
\">
"
);
        $.blockUI({
            message: $(
'
#
' 
+
 imgID 
+ 
'
_HD
'
).click($.unblockUI),
            css: {
                centerY: 
true
,
                top: ($(window).height() 
-
 hd_height) 
/ 
2 
+ 
'
px
'
,
                left: ($(window).width() 
-
 hd_width) 
/ 
2 
+ 
'
px
'
,
                width: hd_width 
+ 
'
px
'
,
                height: hd_height 
+ 
'
px
'
            },
            fadeIn: 
700
,
            fadeOut: 
700
        });
        $(
'
.blockOverlay
'
).attr(
'
title
'
'
点击收起
'
).click($.unblockUI);
        
var
 i 
=
 setInterval(
function
 () {
            
var
 h 
=
 $(
'
#
' 
+
 imgID 
+ 
'
_HD
'
).height();
            $(
'
#
' 
+
 imgID 
+ 
'
_HD
'
).css(
'
margin-top
'
, (hd_height 
-
 h) 
/ 
2 
+ 
'
px
'
);
            
if
 (h 
> 
0
) {
                clearInterval(i);
            }
        }, 
1000
);
    }
    
//
#endregion
    
//
#region 绑定事件
    
function
 bindZPClick(hidButton,index) {
        
var
 count 
=
 $(
"
.banner_list
"
).eq(index).children(
'
a
'
).length;
        $(
"
.banner_list
"
).eq(index).children(
'
a:not(:first-child)
'
).hide();
        editBannerinfo(hidButton,index);
        $(
"
.banner_ul
"
).eq(index).children(
'
li
'
).click(
function
 () {
            
var
 i 
=
 $(
this
).text() 
- 
1
//
获取Li元素内的值,即1,2,3,4
            
if
 (i 
>=
 count) 
return
;
            $(
"
.banner_list
"
).eq(index).children(
'
a
'
).filter(
"
:visible
"
).fadeOut(
500
).parent().children().eq(i).fadeIn(
1000
);
            $(
this
).css({ 
"
background
"
"
#be2424
"
'
color
'
'
#000
'
 }).siblings().css({ 
"
background
"
"
#6f4f67
"
'
color
'
'
#fff
'
 });
        });
    }
    
function
 editBannerinfo(hidButton, index) {
        
if
 (hidButton 
== 
'
undefined
' 
||
 hidButton) {
            hidButton 
= 
false
;
            $(
'
.banner_bg
'
).eq(index).remove();
        }
        
else
 {
            $(
"
.banner_info
"
).eq(index).empty();
            
if
 ($(
'
.banner_ul
'
).eq(index).children(
'
li
'
).length 
> 
4
) {
                $(
"
.banner_info
"
).eq(index).append(
"
<image alt='新增' id='
" 
+
 index 
+ 
"
_imgRyAdd' src='/FM/Content/Images/plus.jpg' οnclick='$.growlUI(\"最多只能上传5张照片\",null,1000);$(\"div.growlUI\").attr(\"class\",\"growlUI_Error\");' />
"
);
            }
            
else
 {
                $(
"
.banner_info
"
).eq(index).append(
"
<image alt='新增' id='
" 
+
 index 
+ 
"
_imgRyAdd' src='/FM/Content/Images/plus.jpg' />
"
);
            }
            $(
"
.banner_info
"
).eq(index).append(
"
<image alt='删除' id='
" 
+
 index 
+ 
"
_imgRyDel' src='/FM/Content/Images/minus.jpg' οnclick='delZP(
" 
+
 index 
+ 
"
);' />
"
)
            .append(
"
<image alt='修改' id='
" 
+
 index 
+ 
"
_imgRyModify' src='/FM/Content/Images/edit2.png'  />
"
);
            setTimeout(
function
 () {
                setRyUpload(
'
add
'
, index);
                setRyUpload(
'
modify
'
, index);
            }, 
3000
);
        }
    }
    
//
#endregion
    
//
#region 初始化人员上传控件
    
function
 setRyUpload(operation, index) {
        
var
 url;
        
var
 mess;
        
var
 selector;
        
var
 setdata;
        
var
 zpid 
=
 $(
"
.banner_list
"
).eq(index).children(
'
a
'
).filter(
"
:visible
"
).children().attr(
"
id
"
);
        
var
 content 
= 
''
;
        
if
 (operation 
=== 
'
add
'
) {
            url 
= 
'
/FM/Modify/AddRyImg
'
;
            mess 
= 
'
新增图片成功!
'
;
            content 
= 
'
相片ID:
'
;
            selector 
= 
'
#
'
+
index
+
'
_imgRyAdd
'
;
            setdata 
=
 { 
'
YWDTID
'
: $(
'
#PhotoYWdtid
'
).val() };
        }
        
else
 {
            url 
= 
'
/FM/Modify/ModifyRyImg
'
;
            mess 
= 
'
修改图片成功!
'
;
            content 
= 
'
相片ID:
' 
+
 zpid;
            selector 
= 
'
#
' 
+
 index 
+ 
'
_imgRyModify
'
;
            setdata 
=
 { 
'
photoID
'
: zpid };
        }
        
var
 upload 
= 
new
 AjaxUpload(
            $(selector),
            {
                action: url,
                onSubmit: 
function
 () { 
this
.disable(); },
                responseType: 
"
json
"
,
                onComplete: 
function
 (file, response) {
                    refreshTB(index);
                    
if
 (response 
== 
'
1
'
) {
                        $.growlUI(mess, 
null
2000
);
                    }
                    
else
 {
                        $.growlUI(
'
上传失败
'
null
2000
);
                    }
                }
            });
        upload.setData(setdata);
    }
    
//
#endregion
    
//
#region 删除照片
    
function
 delZP(index) {
        
if
 (window.confirm(
"
确认删除当前照片吗?
"
)) {
            
var
 zpid 
=
 $(
"
.banner_list
"
).eq(index).children(
'
a
'
).filter(
"
:visible
"
).children().attr(
"
id
"
);
            
var
 mess;
            $.post(
            
'
/FM/Modify/DltRyImg
'
, { photoID: zpid },
            
function
 (result) {
                mess 
=
 result 
== 
1 
? 
'
删除成功
'
 : 
'
删除失败
'
;
                $.growlUI(mess, 
'
相片ID:
' 
+
 zpid, 
2000
);
                refreshTB(index);
            }
            );
        }
    }
    
//
#endregion
    
//
#region 刷新照片
    
function
 refreshTB(index) {
        
var
 ywdtid 
=
 $(
'
#PhotoYWdtid
'
).val();
        
var
 time 
=
 (
new
 Date()).toString();
        
var
 hd_width 
=
 $(
'
#HD_Width
'
).val();
        
var
 hd_height 
=
 $(
'
#HD_Height
'
).val();
        $(
'
.banner_f
'
).eq(index).parent().empty().load(
'
/FM/Modify/BannerPhoto
'
,
        { YWDTID: ywdtid, timeStamp: time, width: hd_width, height: hd_height },
        
function
 () {
            fillRYPhoto($(
'
#ZPDTID
'
).val(), 
false
, index);
        });
    }
    
//
#endregion
<
/
script>

    这里详细说一下显示大图的问题,由于图片在数据库里是以blob的形式存储,又担心图片的文件存储问题,所以自始自终图片都不以文件的形式存储,而用户又要求显示大图的时候要自适应宽度和高度,也就是不能变形又不能溢出自定义的外框,这样就要进行图片处理。下面是byte[]和 Image互转的两个方法:

 View Code

public 
static
 Image ConvertToImg(Byte[] byte_img)
        {
            
using
 (MemoryStream stream 
= 
new
 MemoryStream(byte_img))
            {
                Image img 
=
 Image.FromStream(stream);
                
return
 img;
            }
        }
        
public 
static
 Byte[] ConvertToByte(Image img)
        {
            
using
 (MemoryStream stream
=
new
 MemoryStream())
            {
                img.Save(stream, ImageFormat.Jpeg);
                
return
 stream.ToArray();
            }
        }

 显示大图时我用了blockUI,用法见。小图点击时直接请求数据库原图并将需显示大小尺寸做入参在后台计算并处理生成缩略图(这里的缩略图生成比较简单,没有做插值算法处理,有兴趣可以自行生成高质量缩略图):

View Code
public
 FileResult GetRyPhotoHDByID(
string
 ZPDTID, 
int
 hd_width, 
int
 hd_height, 
string
 timestamp)
        {
            DataTable dt 
=
 Session[
"
zp
"
as
 DataTable;
            
if
 (dt 
== 
null
)
            {
                
return
 File(Server.MapPath(
"
~/Content/Images/nophoto.jpg
"
), 
"
application/octet-stream
"
);
            }
            DataRow[] dr 
=
 dt.Select(
"
DTID=
" 
+
 ZPDTID);
            
if
 (dr.Count() 
< 
1
)
            {
                
return
 File(Server.MapPath(
"
~/Content/Images/nophoto.jpg
"
), 
"
application/octet-stream
"
);
            }
            Byte[] zpnr 
=
 (Byte[])dr[
0
][
"
ZPNR
"
];
            Image img 
=
 ImageCommon.ConvertToImg(zpnr);
            
double
 a 
=
 Convert.ToDouble(img.Width) 
/
 Convert.ToDouble(img.Height);
//
原图宽高比
            
double
 b 
=
 Convert.ToDouble(hd_width) 
/
 Convert.ToDouble(hd_height);
//
浮动层宽高比
            
double
 w 
=
 img.Width;
//
显示的大图的宽度
            
double
 h 
=
 img.Height;
//
显示的大图的高度
            
if
 (img.Width 
>
 hd_width 
||
 img.Height 
>
 hd_height)
//原图的宽度或高度大于外层宽高则做缩略图,否则显示原图
            {
                
if
 (a 
>
 b)
                {
                    w 
=
 hd_width;
                    h 
=
 Convert.ToDouble(w 
*
 img.Height) 
/
 Convert.ToDouble(img.Width);
                }
                
else
                {
                    h 
=
 hd_height;
                    w 
=
 Convert.ToDouble(h 
*
 img.Width) 
/
 Convert.ToDouble(img.Height);
                }
                Image.GetThumbnailImageAbort myCallback 
= 
new
 Image.GetThumbnailImageAbort(CallBack);
                Image i 
=
 img.GetThumbnailImage(Convert.ToInt32(w), Convert.ToInt32(h), myCallback, IntPtr.Zero);
                Byte[] byte_img 
=
 ImageCommon.ConvertToByte(i);
                
return
 File(byte_img, 
"
application/octet-stream
"
);
            }
            
else
            {
                
return
 File((Byte[])dr[
0
][
"
ZPNR
"
], 
"
application/octet-stream
"
);
            }
        }
        
private 
static 
bool
 CallBack()  
//
委托方法
        {
            
return 
false
;

        } 

    生成之后有一个定位问题,因为返回之后要做居中处理(大图要显示在自定义的层中央,这个自定义层的大小是根据业务自定义的,主要是显示大图的时候用户可能还想看前面的信息),但是图片此时虽然已经生成,但是前台缺未必可以获取到尺寸,这里用了一个小技巧,用一个计时器反复检查图片尺寸直到尺寸大于0时清除计时器:

 

View Code
 
var
 i 
=
 setInterval(
function
 () {
            
var
 h 
=
 $(
'
#
' 
+
 imgID 
+ 
'
_HD
'
).height();
            $(
'
#
' 
+
 imgID 
+ 
'
_HD
'
).css(
'
margin-top
'
, (hd_height 
-
 h) 
/ 
2 
+ 
'
px
'
);
            
if
 (h 
> 
0
) {
                clearInterval(i);
            }
        }, 
1000
);
 

 

 其余的新增,删除修改图片的后台方法比较简单我就不贴了。各位看官有何意见,尽管拍砖~

 

转载于:https://www.cnblogs.com/dzxw2371/archive/2011/05/11/2043001.html

你可能感兴趣的文章
windows 下,CCXT库的安装
查看>>
HDU 1242 Rescue(BFS)
查看>>
centos7.2下安装mantis2.19.0
查看>>
消息扩散(强连通分量)
查看>>
nxlog 日志采集
查看>>
Eclipse常用快捷键
查看>>
异构GoldenGate 12c 双向复制配置
查看>>
01-HTML基础与进阶-day6-录像280
查看>>
你听过稀疏数组(sparseArray)吗?
查看>>
Google的java工具类Guava
查看>>
信息安全系统设计基础实验二报告
查看>>
Linux Shell脚本编程基础(11)
查看>>
Hibernate批量处理数据
查看>>
Entity Framework实体框架快速入门
查看>>
Nvidia显卡安装驱动
查看>>
pom文件解析
查看>>
[51nod] 1257 背包问题 V3
查看>>
[转]rsync的配置与应用
查看>>
【Java】Exception thrown by the agent : java.rmi.server.ExportException: Port already in use: 1099
查看>>
jmeter中jdbc连接数据库——(一)
查看>>