头像选择控件[原创]

  闲着没事,弄了个大家常见的头像选择控件。
虽然是个小东东,但是用处还是蛮多的。比如大道论坛、Blog、聊天室;小到留言本都有可能用的到。麻雀虽小,五脏俱全。开放源代码让大家砸吧。

主要思路:
  用System.IO读取指定文件夹下的所有图片,select中optoins的Value为图片的相对路径,Text为图片的名字。不使用数据库(这样如果头像很多效率可能不是太高),当选择的option变化的时候,显示预览图片(无刷新)。这样,就不能单纯的通过继承DropDownList来实现了,所以只好选择继承WebControl。同时,为了实现数据回发并能够在服务器端取得选择的值,还要继承IPostBackDataHandler接口。

public class FaceSelect : WebControl, IPostBackDataHandler
{
  ……
}



绘制select和img控件的代码如下:

绘制select:

/// <summary>
        
/// 产生选择列表
        
/// </summary>
        
/// <param name="writer"></param>
        
/// 作者:张伟
        
/// 日期:2006-10-20
        private void RenderFaceSelectControl(HtmlTextWriter writer)
        {
            
//获取当前选中的头像
            string dFace = SelectedFace;

            
//向下拉列表表添加属性
            writer.AddAttribute(HtmlTextWriterAttribute.Name, this.ClientID + "_FaceSelect");
            writer.AddAttribute(HtmlTextWriterAttribute.Id, 
this.ClientID + "_FaceSelect");

            
//注册JS
            writer.AddAttribute(HtmlTextWriterAttribute.Onchange, string.Format(HEADER_SELECT_HOOK, this.ClientID + "_FaceSelect"this.ClientID + "_FaceImageShow"));

            
//取得服务器端头像存储的文件夹
            string strServerFacePath = HttpContext.Current.Server.MapPath(FaceUrl);
            
if (!Directory.Exists(strServerFacePath))//如果文件夹不存在
            {
                writer.WriteLine(
string.Format("<option value=\"ERROR\">头像系统出错</option>"));
                
return;
            }

            
//获取所有头像
            string[] faceImages = Directory.GetFiles(strServerFacePath);

            
//开始输出下拉列表
            writer.RenderBeginTag(HtmlTextWriterTag.Select);
            
if (bIsShowNoticeText)//如果显示提示文字
            {
                
//添加提示文字
                if (dFace == strNoSelectImage || dFace == "NULL")
                {
                    writer.WriteLine(
"<option value=\"" + strNoSelectImage + "\" selected>" + strSelectNoticeText + "</option>");
                }
                
else
                {
                    writer.WriteLine(
"<option value=\"" + strNoSelectImage + "\">" + strSelectNoticeText + "</option>");
                }
            }
            
foreach (string faceImage in faceImages)
            {
                
string[] parts = faceImage.Split('\\');
                
string faceImageName = parts[parts.Length - 1];
                FileInfo faceImageInfo 
= new FileInfo(faceImage);
                
string strExtension = faceImageInfo.Extension.ToUpper();

                
if (strExtension == ".GIF" || strExtension == ".JPG" || strExtension == ".PNG" || strExtension == ".BMP")
                {
                    
if (faceImage == HttpContext.Current.Server.MapPath(dFace))
                    {
                        writer.WriteLine(
string.Format("<option value=\"{0}\" selected>{1}</option>", FaceUrl + faceImageName, faceImageName.Remove(faceImageName.LastIndexOf('.'))));
                    }
                    
else
                    {
                        writer.WriteLine(
string.Format("<option value=\"{0}\">{1}</option>", FaceUrl + faceImageName, faceImageName.Remove(faceImageName.LastIndexOf('.'))));
                    }
                }
            }
            writer.RenderEndTag();
        }

绘制Img控件:

 /// <summary>
        
/// 产生图片显示控件
        
/// </summary>
        
/// <param name="writer"></param>
        
/// 作者:张伟
        
/// 日期:2006-10-20
        private void RenderImageShow(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Name, 
this.ClientID + "_FaceImageShow");
            writer.AddAttribute(HtmlTextWriterAttribute.Id, 
this.ClientID + "_FaceImageShow");

            
//如果没有选头像
            if (string.IsNullOrEmpty(strSelectedFace) || strSelectedFace == "NULL" || strSelectedFace == "ERROR")
            {
                
if (bIsShowNoticeText)//如果显示提示文字
                {
                    
if (strNoSelectImage != "NULL" && !string.IsNullOrEmpty(strNoSelectImage))
                    {
                        writer.AddAttribute(HtmlTextWriterAttribute.Src, strNoSelectImage);
                    }
                    
else
                    {
                        writer.AddStyleAttribute(HtmlTextWriterStyle.Display, 
"none");
                        writer.AddStyleAttribute(HtmlTextWriterStyle.Visibility, 
"hidden");
                    }
                }
                
else
                {
                    
//取得服务器端头像存储的文件夹
                    string strServerFacePath = HttpContext.Current.Server.MapPath(FaceUrl);
                    
if (!Directory.Exists(strServerFacePath))//如果文件夹不存在
                    {
                        writer.WriteLine(
string.Format("<option value=\"ERROR\">头像系统出错</option>"));
                        
return;
                    }

                    
//获取所有头像
                    string[] faceImages = Directory.GetFiles(strServerFacePath);

                    
//是否现实图片
                    bool bShowFace = false;

                    
foreach (string faceImage in faceImages)
                    {
                        
string[] parts = faceImage.Split('\\');
                        
string faceImageName = parts[parts.Length - 1];
                        FileInfo faceImageInfo 
= new FileInfo(faceImage);
                        
string strExtension = faceImageInfo.Extension.ToUpper();

                        
if (strExtension == ".GIF" || strExtension == ".JPG" || strExtension == ".PNG" || strExtension == ".BMP")
                        {
                            writer.AddAttribute(HtmlTextWriterAttribute.Src, strFaceUrl 
+ faceImageName);
                            bShowFace 
= true;//显示
                            break;
                        }
                    }
                    
if (!bShowFace)
                    {
                        writer.AddStyleAttribute(HtmlTextWriterStyle.Display, 
"none");
                        writer.AddStyleAttribute(HtmlTextWriterStyle.Visibility, 
"hidden");
                    }
                }
            }
            
else
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Src, strSelectedFace);
            }

            writer.RenderBeginTag(HtmlTextWriterTag.Img);
            writer.RenderEndTag();
        }

各位应该看到了,注册在Selec中注册了一个JS事件,主要实现当选择的图片变化时显示预览图片的功能。相关代码如下:

private const string HEADER_SELECT_SCRIPT =
@"<script language='javascript'>
  function ShowFace(ddlSelect, imgFaceShow)
  {
        var selectedValue = ddlSelect.options[ddlSelect.selectedIndex].value;
        if(selectedValue == 'NULL' || selectedValue == '')
        {
            imgFaceShow.style.visibility='hidden';
            imgFaceShow.style.display='none';
        }
        else if(selectedValue == 'ERROR')
        {
            ddlSelect.disabled='disabled';
        }
        else
        {
            imgFaceShow.src = ddlSelect.options[ddlSelect.selectedIndex].value;
            imgFaceShow.style.visibility='visible';
            imgFaceShow.style.display='block';
        }
    }
  </script>
";
        
private const string HEADER_SELECT_SCRIPT_ID = "a84f2d22-1cc6-473d-ae14-9cc3e7843e46";
        
private const string HEADER_SELECT_HOOK = "ShowFace({0}, {1});";

这样,在重写OnPreRender的时候就可以注册这段JS了。

protected override void OnPreRender(EventArgs e)
        {
            
base.OnPreRender(e);
            Page.RegisterRequiresPostBack(
this);
            Page.ClientScript.GetPostBackClientHyperlink(
this"");
            
if (!Page.ClientScript.IsClientScriptBlockRegistered(HEADER_SELECT_SCRIPT_ID))
            {
                Page.ClientScript.RegisterClientScriptBlock(Type.GetType(
"System.String"), HEADER_SELECT_SCRIPT_ID, HEADER_SELECT_SCRIPT);
            }
        }

实现IPostBackDataHandler并保存选择状态,这里定义了一个属性来取得选择的值:

[Description("获取选中的头像"), Browsable(false)]
        
public string SelectedFace
        {
            
get
            {
                
if (string.IsNullOrEmpty(strSelectedFace) || strSelectedFace == "NULL" || strSelectedFace == "ERROR")
                {
                    
return strNoSelectImage;
                }
                
else
                {
                    
return strSelectedFace;
                }
            }
            
set
            {
                strSelectedFace 
= value;
            }
        }
...............
public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
        {
            
//获取选中的头像Url
            string selectedFaceUrl = (string)postCollection[this.ClientID + "_FaceSelect"];

            
if (!string.IsNullOrEmpty(selectedFaceUrl) && selectedFaceUrl != "NULL")
            {
                SelectedFace 
= selectedFaceUrl;
                
return true;
            }
            
return false;
        }

另外给控件添加了一个事件,就是当选择的头像变化的时候执行回发:

        private static object FaceChangeEvent = new object();

        
public event EventHandler FaceChanged
        
{
            add
            
{
                Events.AddHandler(FaceChangeEvent, value);
            }

            remove
            
{
                Events.RemoveHandler(FaceChangeEvent, value);
            }

        }


        
protected virtual void OnFaceChanged(EventArgs args)
        
{
            EventHandler handler 
= (EventHandler)Events[FaceChangeEvent];
            
if (handler != null)
            
{
                handler(
this, args);
            }

        }


……


//IPostBackDataHandler的方法实现
        public void RaisePostDataChangedEvent()
        
{
            
//注册事件
            OnFaceChanged(EventArgs.Empty);
        }

到这里就基本上差不多了,另外加了一些是否出现头像选择提示文字之类的功能,具体请看源代码吧!

运行效果:

默认有提示选择头像的文字!

选定头像

提交


后记:
这里仅仅是通过文件系统来获取头像,如果能跟XML结合起来使用想必效果会更好。
废话不说了,上源代码:

TW.Web.UI.rar
posted @ 2006-10-20 19:13  夜雨冷滴芭蕉  阅读(3158)  评论(9编辑  收藏  举报