widget.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="widget.ascx.cs" Inherits="Widgets.YahooIMGnews.Widget" %>
<ol runat="server" id="olLinks" />
<div>
<ul runat="server" id="ulLinks" />
<a class="left" href="#">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a class="right" href="#">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</div>
<script type="text/javascript">
$("ul > li[data-id]").hover(
function () {
$('li[data-id]').removeClass("active");
$('ol > li[data-id=' + $(this).attr("data-id") + ']').addClass("active");
$(this).addClass("active");
},
function () {
$(this).addClass("active");
}
)
</script>
namespace Widgets.YahooIMGnews { using App_Code.Controls;
using BlogEngine.Core;
using System;
using System.Xml; /// <summary>
/// 部件
/// </summary>
public partial class Widget : WidgetBase { #region 属性 /// <summary>
/// 获取一个值,该值指示部件是否是可编辑的。
/// 可以编辑
/// </summary>
public override bool IsEditable {
get { return true; }
} /// <summary>
/// 小部件的名称。
/// Default IMGNews MainTop
/// 与目录名称必须一致
/// </summary>
public override string Name {
get { return "YahooIMGnews"; }
} #endregion #region 公共方法 /// <summary>
/// 该方法代替Page_Load工作。
/// 使用这种方法代替Page_Load数据绑定等。
/// </summary>
public override void LoadWidget() {
var settings = this.GetSettings();
var doc = new XmlDocument(); if (settings["content"] != null) {
doc.InnerXml = settings["content"];
} var links = doc.SelectNodes("//link"); if (links == null) {
return;
} if (links.Count == 0) {
this.Visible = false;
} else {
string active = "active";
int i = 0;
foreach (XmlNode node in links) {
this.olLinks.InnerHtml += String.Format(
"<li data-id=\"{7}\" class=\"{0}\"><a href=\"{4}\" target=\"_blank\"><img src=\"{1}{2}/{3}\" /></a><div><h4><a href=\"{4}\" target=\"_blank\">{5}</a></h4><p>{6}</p></div></li>",
active,
Utils.ApplicationRelativeWebRoot,
settings["imagefolder"],
node.Attributes["img"].InnerText,
node.Attributes["url"].InnerText,
node.Attributes["title"].InnerText,
node.Attributes["explain"].InnerText,
i
);
this.ulLinks.InnerHtml += String.Format(
"<li data-id=\"{6}\" class=\"{0}\"><a href=\"{4}\" target=\"_blank\"><img src=\"{1}{2}/{3}\" /><p>{5}</p></a></li>",
active,
Utils.ApplicationRelativeWebRoot,
settings["imagefolder"],
ThumbFileName(node.Attributes["img"].InnerText),
node.Attributes["url"].InnerText,
node.Attributes["title"].InnerText,
i
);
active = "";
++i;
}
}
}
#endregion #region 私有方法 缩略图文件名 /// <summary>
/// 缩略图文件名
/// </summary>
private string ThumbFileName(string fileName) {
var fInfo = new System.IO.FileInfo(fileName);
return fileName.Replace(fInfo.Extension, "_thumb" + fInfo.Extension);
} #endregion } }
edit.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="edit.ascx.cs" Inherits="Widgets.YahooIMGnews.Edit" %>
<div class="form-horizontal">
<div class="form-group">
<label for="<%=txtTitle.ClientID %>" class="col-sm-2 control-label">文章标题:</label>
<div class="col-sm-7">
<asp:TextBox ID="txtTitle" class="form-control" runat="server" placeholder="文章标题"></asp:TextBox>
</div>
<div class="col-sm-3">
<p class="form-control-static">
<asp:RequiredFieldValidator runat="Server" ControlToValidate="txtTitle" ErrorMessage="请输入标题" ValidationGroup="add" />
</p>
</div>
</div>
<div class="form-group">
<label for="<%=txtExplain.ClientID %>" class="col-sm-2 control-label">文章说明:</label>
<div class="col-sm-7">
<textarea runat="server" id="txtExplain" class="form-control" rows="3" placeholder="文章说明(简介)"></textarea>
</div>
<div class="col-sm-3">
<p class="form-control-static">
<asp:RequiredFieldValidator runat="Server" ControlToValidate="txtExplain" ErrorMessage="请输入文章说明(简介)" ValidationGroup="add" />
</p>
</div>
</div>
<div class="form-group">
<label for="<%=txtUrl.ClientID %>" class="col-sm-2 control-label">文章链接:</label>
<div class="col-sm-7">
<asp:TextBox ID="txtUrl" class="form-control" runat="server" placeholder="Url"></asp:TextBox>
</div>
<div class="col-sm-3">
<p class="form-control-static">
<asp:RegularExpressionValidator runat="Server" ControlToValidate="txtUrl" ValidationExpression="(http://|https://|)([\w-]+\.)+[\w-]+(/[\w- ./?%&=;~]*)?"
ErrorMessage="请输入有效的网址" ValidationGroup="add" />
</p>
</div>
</div>
<div class="form-group">
<label for="<%=txtUploadImage.ClientID %>" class="col-sm-2 control-label">图片上传:</label>
<div class="col-sm-4">
<asp:FileUpload runat="server" ID="txtUploadImage" />
<p class="help-block">上传图片请先修改大小、宽高.</p>
</div>
<div class="col-sm-1">
<label for="<%=txtUrl.ClientID %>">图宽:</label>
<asp:TextBox ID="txtWidth" class="form-control" runat="server" placeholder="数字"></asp:TextBox>
</div>
<div class="col-sm-1">
<label for="<%=txtHeight.ClientID %>">图高:</label>
<asp:TextBox ID="txtHeight" class="form-control" runat="server" placeholder="数字"></asp:TextBox>
</div>
<div class="col-sm-1">
<label for="<%=txtMaxItems.ClientID %>">数量:</label>
<asp:TextBox ID="txtMaxItems" class="form-control" runat="server" placeholder="数字"></asp:TextBox>
</div>
<div class="col-sm-2">
<label for="<%=txtImageFolder.ClientID %>">保存目录:</label>
<asp:TextBox ID="txtImageFolder" class="form-control" runat="server" Text="Content/IMGNews" ReadOnly="True" placeholder="路径"></asp:TextBox>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<asp:Button runat="server" CssClass="btn btn-default" ID="btnAdd" Text="添加" />
</div>
</div>
</div> <div class="table-responsive">
<asp:GridView runat="server" ID="grid" AutoGenerateColumns="False" AutoGenerateDeleteButton="True" AutoGenerateEditButton="True" CssClass="table">
<Columns>
<asp:TemplateField HeaderText="图片">
<ItemTemplate>
<img src="/Content/IMGNews/<%# thumbName(Eval("img").ToString()) %>" />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtImg" Text='<%# Eval("img") %>' />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="文章标题">
<ItemTemplate>
<%# Eval("title") %>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtTitle" Text='<%# Eval("title") %>' />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="文章说明">
<ItemTemplate>
<%# Eval("explain") %>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtExplain" Text='<%# Eval("explain") %>' />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="文章链接 Url">
<ItemTemplate>
<%# Eval("url")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtUrl" Text='<%# Eval("url") %>' />
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
namespace Widgets.YahooIMGnews { using App_Code.Controls;
using BlogEngine.Core;
using System;
using System.Data;
using System.Drawing;
using System.IO;
using System.Web.UI.WebControls;
using System.Xml; /// <summary>
/// YahooIMGnews 窗体小部件的设置与编辑.
/// </summary>
public partial class Edit : WidgetEditBase {
#region 公共方法 /// <summary>
/// 将此基本小部件设置如标题。
/// </summary>
public override void Save() {
this.Doc();
} #endregion #region 方法 /// <summary>
/// 获取XML文档。
/// </summary>
/// <returns>XML文档。</returns>
private XmlDocument Doc() {
var settings = this.GetSettings();
var doc = new XmlDocument();
if (settings["content"] != null) {
doc.InnerXml = settings["content"];
} return doc;
} /// <summary>
/// 加载事件 <see cref="E:System.Web.UI.Control.Load"/>
/// </summary>
/// <param name="e">这个 <see cref="T:System.EventArgs"/> 事件包含的数据.</param>
protected override void OnLoad(EventArgs e) {
base.OnLoad(e); if (!this.Page.IsPostBack) {
this.BindGrid();
} this.grid.RowEditing += this.GridRowEditing;
this.grid.RowUpdating += this.GridRowUpdating;
this.grid.RowCancelingEdit += (o, args) => this.grid.EditIndex = -1;
this.grid.RowDeleting += this.GridRowDeleting;
this.btnAdd.Click += this.BtnAddClick; var settings = this.GetSettings();
this.txtWidth.Text = settings.ContainsKey("imagewidth") == true ? settings["imagewidth"] : "704.5";
this.txtHeight.Text = settings.ContainsKey("imageheight") == true ? settings["imageheight"] : "250";
this.txtMaxItems.Text = settings.ContainsKey("imagemaxitems") == true ? settings["imagemaxitems"] : "50";
} /// <summary>
/// 表格中删除事件。
/// </summary>
/// <param name="sender">
/// 这一事件的来源。
/// </param>
/// <param name="e">
/// 这个 <see cref="System.Web.UI.WebControls.GridViewDeleteEventArgs"/> 事件包含的数据。
/// </param>
private void GridRowDeleting(object sender, GridViewDeleteEventArgs e) {
var doc = this.Doc();
var row = this.grid.DataKeys[e.RowIndex];
if (row != null) {
var id = (string)row.Value;
var node = doc.SelectSingleNode(string.Format("//link[@id=\"{0}\"]", id));
if (node == null) {
return;
} if (node.ParentNode != null) {
node.ParentNode.RemoveChild(node);
}
} this.Save(doc);
this.BindGrid();
} /// <summary>
/// 表格中更新事件。
/// </summary>
/// <param name="sender">
/// 这一事件的来源。
/// </param>
/// <param name="e">
/// 这个 <see cref="System.Web.UI.WebControls.GridViewUpdateEventArgs"/> 事件包含的数据。
/// </param>
private void GridRowUpdating(object sender, GridViewUpdateEventArgs e) {
var doc = this.Doc();
var row = this.grid.DataKeys[e.RowIndex];
if (row != null) {
var id = (string)row.Value;
var textboxImg = (TextBox)this.grid.Rows[e.RowIndex].FindControl("txtImg");
var textboxTitle = (TextBox)this.grid.Rows[e.RowIndex].FindControl("txtTitle");
var textboxExplain = (TextBox)this.grid.Rows[e.RowIndex].FindControl("txtExplain");
var textboxUrl = (TextBox)this.grid.Rows[e.RowIndex].FindControl("txtUrl");
var node = doc.SelectSingleNode(string.Format("//link[@id=\"{0}\"]", id)); if (node == null) {
return;
} if (node.Attributes != null) {
node.Attributes["img"].InnerText = textboxImg.Text.Trim();
node.Attributes["title"].InnerText = textboxTitle.Text.Trim();
node.Attributes["explain"].InnerText = textboxExplain.Text.Trim();
node.Attributes["url"].InnerText = textboxUrl.Text.Trim();
}
} this.grid.EditIndex = -1;
this.Save(doc);
this.BindGrid();
} /// <summary>
/// 表格中编辑事件
/// </summary>
/// <param name="sender">
/// 这一事件的来源。
/// </param>
/// <param name="e">
/// 这个 <see cref="System.Web.UI.WebControls.GridViewEditEventArgs"/> 事件包含的数据。
/// </param>
private void GridRowEditing(object sender, GridViewEditEventArgs e) {
this.grid.EditIndex = e.NewEditIndex;
this.BindGrid();
} /// <summary>
/// 填充数据。
/// </summary>
private void BindGrid() {
var doc = this.Doc();
var list = doc.SelectNodes("//link");
if (list == null || list.Count <= 0) {
return;
} using (var reader = new XmlTextReader(doc.OuterXml, XmlNodeType.Document, null)) {
var ds = new DataSet();
ds.ReadXml(reader);
this.grid.DataSource = ds;
this.grid.DataKeyNames = new[] { "id" };
this.grid.DataBind();
ds.Dispose();
}
} /// <summary>
/// 保存指定的xml文档。
/// </summary>
/// <param name="doc">The xml document.</param>
private void Save(XmlNode doc) {
var settings = this.GetSettings();
settings["ImageWidth"] = this.txtWidth.Text.Trim(); // 图片宽度
settings["ImageHeight"] = this.txtHeight.Text.Trim(); // 图片高度
settings["ImageMaxItems"] = this.txtMaxItems.Text.Trim(); // 最大展示图片数量
settings["ImageFolder"] = this.txtImageFolder.Text.Trim(); // 图片文件存储目录
settings["content"] = doc.InnerXml;
this.SaveSettings(settings);
} /// <summary>
/// 处理单击事件btnAdd。
/// 添加事件
/// </summary>
/// <param name="sender">这一事件的来源。</param>
/// <param name="e">这个 <see cref="System.EventArgs"/> 事件包含的数据。</param>
private void BtnAddClick(object sender, EventArgs e) {
//判断上传控件中是否有值
if (this.txtUploadImage.HasFile == false) {
Response.Write("<script>alert('没有选择图片')</script>");
} else {
string fType = txtUploadImage.PostedFile.ContentType;//获取图像的类型
if (fType == "image/bmp" || fType == "image/gif" || fType == "image/pjpeg" || fType == "image/jpeg" || fType == "image/x-png" || fType == "image/png") {
try {
var doc = this.Doc();
var links = doc.SelectSingleNode("links");
if (links == null) {
links = doc.CreateElement("links");
doc.AppendChild(links);
} XmlNode link = doc.CreateElement("link"); var id = doc.CreateAttribute("id");
id.InnerText = Guid.NewGuid().ToString();
if (link.Attributes != null) {
link.Attributes.Append(id);
} // img
var img = doc.CreateAttribute("img");
img.InnerText = this.txtUploadImage.FileName.ToLowerInvariant();
Upload();// 私有方法 文件上传
if (link.Attributes != null) {
link.Attributes.Append(img);
}
// title
var title = doc.CreateAttribute("title");
title.InnerText = this.txtTitle.Text.Trim();
if (link.Attributes != null) {
link.Attributes.Append(title);
}
// explain
var explain = doc.CreateAttribute("explain");
explain.InnerText = this.txtExplain.Value.Trim();
if (link.Attributes != null) {
link.Attributes.Append(explain);
}
//url
var url = doc.CreateAttribute("url");
url.InnerText = this.txtUrl.Text.Trim();
if (link.Attributes != null) {
link.Attributes.Append(url);
} links.AppendChild(link);
this.Save(doc);
this.BindGrid();
} catch (Exception ex) {
Utils.Log("YahooIMGnews-编辑页面-添加", ex);
}
} else {
Response.Write("<script>alert('图片格式出错');</script>");
}
}
} #endregion #region 私有方法 文件上传 /// <summary>
/// 文件上传
/// </summary>
private void Upload() {
// 图片保存绝对全路径 文件夹
var folder = Server.MapPath(Utils.ApplicationRelativeWebRoot + this.txtImageFolder.Text.Trim());
// 图片保存绝对全路径 文件名称
var fileName = Path.Combine(folder, txtUploadImage.FileName.ToLowerInvariant());
// 判断文件目录是否存在,不存在就建立。
if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);
// 判断当前文件是否有预上传同名文件,有就删除。
if (File.Exists(fileName))
File.Delete(fileName);
// 保存文件
txtUploadImage.PostedFile.SaveAs(fileName); // 生成缩略图
MakeThumbnail(fileName, thumbName(fileName), 130, 48, "HW"); //System.Drawing.Image image = System.Drawing.Image.FromFile(fileName);
//System.Drawing.Image thumb = image.GetThumbnailImage(130, 48, () => false, IntPtr.Zero);
// 保存缩略图文件
//thumb.Save(thumbName);
} /// <summary>
/// 缩略图文件名
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public string thumbName(string fileName) {
var fInfo = new System.IO.FileInfo(fileName);
return fileName.Replace(fInfo.Extension, "_thumb" + fInfo.Extension);
} /// <summary>
/// 生成缩略图
/// </summary>
/// <param name="originalImagePath">源图路径(物理路径)</param>
/// <param name="thumbnailPath">缩略图路径(物理路径)</param>
/// <param name="width">缩略图宽度</param>
/// <param name="height">缩略图高度</param>
/// <param name="mode">生成缩略图的方式</param>
private void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode) {
// 判断当前文件是否有预上传同名缩略图文件,有就删除。
if (File.Exists(thumbnailPath))
File.Delete(thumbnailPath); System.Drawing.Image originalImage = System.Drawing.Image.FromFile(originalImagePath); int towidth = width;
int toheight = height; int x = 0;
int y = 0;
int ow = originalImage.Width;
int oh = originalImage.Height; switch (mode) {
case "HW"://指定高宽缩放(可能变形)
break;
case "W"://指定宽,高按比例
toheight = originalImage.Height * width / originalImage.Width;
break;
case "H"://指定高,宽按比例
towidth = originalImage.Width * height / originalImage.Height;
break;
case "Cut"://指定高宽裁减(不变形)
if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight) {
oh = originalImage.Height;
ow = originalImage.Height * towidth / toheight;
y = 0;
x = (originalImage.Width - ow) / 2;
} else {
ow = originalImage.Width;
oh = originalImage.Width * height / towidth;
x = 0;
y = (originalImage.Height - oh) / 2;
}
break;
default:
break;
} //新建一个bmp图片
System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight); //新建一个画板
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap); //设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; //设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; //清空画布并以透明背景色填充
g.Clear(Color.Transparent); //在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
new Rectangle(x, y, ow, oh),
GraphicsUnit.Pixel); try {
//以jpg格式保存缩略图
bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg);
} catch (System.Exception e) {
throw e;
} finally {
originalImage.Dispose();
bitmap.Dispose();
g.Dispose();
}
} #endregion
} }