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
}
}