当前位置:  编程技术>.net/c#/asp.net
本页文章导读:
    ▪onmouseover和onmouseout应用于RadioButtonList或CheckBoxList      一直想实现onmouseover和onmouseout应用于RadioButtonList或CheckBoxList控件上,今晚终于有时间实现它。此功能就是当鼠标经过时RadioButtonList或CheckBoxList每一个Item时,让Item有特效显示,离开时,恢复原.........
    ▪Winform开发框架之通用短信邮件通知模块      在做Winform项目的时候,一直有一个梦想,就是希望把所有的组件模块组合即可组装成一个完整的项目系统(或者至少可以大部分完成)。在之前介绍的《Winform开发框架之通用附件管理模块》.........
    ▪WPF:把Task, Lazy<T>和INotifyPropertyChanged组装成一个超级属性      这三个元素,Task代表着异步多线程,Lazy<T>代表着延迟初始化,INotifyPropertyChanged则代表着属性改变通知(多用于MVVM模式中)。那么如果把这三个元素组合起来就是一个异步延迟初始化的IN.........

[1]onmouseover和onmouseout应用于RadioButtonList或CheckBoxList
    来源:    发布时间: 2013-10-28

一直想实现onmouseover和onmouseout应用于RadioButtonList或CheckBoxList控件上,今晚终于有时间实现它。此功能就是当鼠标经过时RadioButtonList或CheckBoxList每一个Item时,让Item有特效显示,离开时,恢复原样。可以看到效果:

RadioButtonList效果:


CheckBoxList效果:

 

这资实现数据,Insus.NET准备了五行(Five Phases)

 

创建一个对象[Five Phases]:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Summary description for FivePhases
/// </summary>
public class FivePhases
{
private int _ID;
private string _Name;

public int ID
{
get { return _ID; }
set { _ID = value; }
}

public string Name
{
get { return _Name; }
set { _Name = value; }
}

public FivePhases()
{
//
// TODO: Add constructor logic here
//
}

public FivePhases(int id, string name)
{
this.ID = id;
this._Name = name;
}
}

 

private List<FivePhases> GetFivePhases()
{
List<FivePhases> ListFH = new List<FivePhases>();
FivePhases fh = new FivePhases();
fh.ID = 1;
fh.Name = "木";
ListFH.Add(fh);

fh = new FivePhases();
fh.ID = 2;
fh.Name = "火";
ListFH.Add(fh);

fh = new FivePhases();
fh.ID = 3;
fh.Name = "土";
ListFH.Add(fh);

fh = new FivePhases();
fh.ID = 4;
fh.Name = "金";
ListFH.Add(fh);

fh = new FivePhases();
fh.ID = 5;
fh.Name = "水";
ListFH.Add(fh);

return ListFH;
}


此时,你可以拉一个RadioButtonList或是CheckBoxList控件至网页中,此例以RadioButtonList控件为例。

<asp:CheckBoxList ID="RadioButtonListFivePhases" runat="server" RepeatDirection="Horizontal"></asp:CheckBoxList>


然后在cs绑定数据:

using System.Data.OleDb;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Insus.NET;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
Data_Binding();
}

private void Data_Binding()
{
this.RadioButtonListFivePhases.DataSource = GetFivePhases();
this.RadioButtonListFivePhases.DataTextField = "Name";
this.RadioButtonListFivePhases.DataValueField =
    
[2]Winform开发框架之通用短信邮件通知模块
    来源:    发布时间: 2013-10-28

在做Winform项目的时候,一直有一个梦想,就是希望把所有的组件模块组合即可组装成一个完整的项目系统(或者至少可以大部分完成)。在之前介绍的《Winform开发框架之通用附件管理模块》里面介绍了我的Winform开发框架的版图,里面包含了我对Winform模块化的一系列规划的组件,组件尽可能是适用于大多数的业务环境组合,以达到最大程度的重用和高效开发。

Winform开发框架是我集多年开发经验以及积累而成,很多细节之处润物细无声,但却是精粹心得所至,很多地方都希望是精益求精,力求把框架中的模块当成一把把神兵利器,用到的时候,马上就可以派生用场解决问题,这样可以避免给客户开发业务的时候,延误战机,或者因为事无巨细,都要从头来过,效率大打折扣,而且时间和金钱的大投入也未见得取得好的效果。

上两篇介绍了WInform框架中的通用定时服务管理模块,《Winform开发框架之通用定时服务管理》、《Winform开发框架之通用定时服务管理2---如何开发定时服务应用》,主要介绍主要在常规数据同步的时候,如何快速利用定时服务管理的通用模块,加上插件化的一些同步业务实现模块,实现强大、高效、松耦合的定时服务管理。本篇继续介绍Winform开发框架中的版图部分,通用短信邮件通知模块。

开发这个模块的初衷是我在开发过的很多项目中,发现或多或少,都有短信通知、邮件通知、站内通知信息的需求,短信和邮件用的很多,也是大多数业务系统重复建设的模块之一,如单位办理业务要通知申请人,公司和客户沟通交流,公司内部员工沟通,这些可能是通过短信、邮件或者站内信息(或叫系统内部的通知信息)。如果这些模块能够快速搭建的话,对项目组来说,节省的时间,提高的是效率。对单位企业来说,这是高质量代码的保证,重复利用更可也减少重复的人力投资和成本支出。

1、模块设计

首先我们知道,短信、邮件、站内信息这几个业务的发送信息的时候,我们都希望记录相关的发送例子,其中短信实现发送的机制比较多,可能通过自己企业内部的短信MAS代理机来发送,也可能是通过购买的外部的WebService服务发送,因此通过插件模块的机制,实现短信发送逻辑的动态加载;邮件发送则利用.NET的邮件发送API,加上企业或者个人邮件发送参数即可实现,也是通过插件方式实现发送逻辑的动态加载;站内信息主要就是数据库记录,然后定时检测是否有记录即可,相对比较简单。

短信、邮件、站内信息的数据库设计,如下图所示,他们三者之间共用一个模板表,通过不同的TemplateType来识别不同的信息模板,这样信息模板表可以为短信、邮件、站内信息做更好的引用。

这里我们可以看到,我主要就是设计几个表来存储他们的发送记录,对于具体的短信发送,邮件发送,我们采用插件方式实现具体发送逻辑的封装,如下所示。

 

其中邮件发送接口和短信发送接口定义如下,方便实现基于插件方式的发送逻辑模块。

public interface IMailSend
{
/// <summary>
/// 发送外部邮件(自定义邮件配置,如个人邮件)
/// </summary>
/// <param name="mailInfo">发送邮件信息</param>
/// <param name="settingInfo">SMTP协议设置信息</param>
/// <returns></returns>
CommonResult Send(MailInfo mailInfo, SmtpSettingInfo settingInfo);

/// <summary>
/// 发送外部邮件(系统配置,系统邮件)
/// </summary>
/// <param name="mailInfo">发送邮件信息</param>
/// <returns></returns>
CommonResult Send(MailInfo mailInfo);
}



public interface ISmsSend
{
/// <summary>
/// 发送短信
/// </summary>
/// <param name="content">短信内容</param>
/// <param name="mobiles">手机号码(多个号码用”,”分隔)</param>
/// <param name="sendTime">预约发送时间</param>
/// <returns></returns>
CommonResult Send(string content, string mobiles, DateTime? sendTime);
}

2、软件使用界面

1)短信界面功能

具体的模块界面如下,输入信息发送后成功的界面如下所示。

 发送信息后,手机收到的结果如下所示。

短信还可以使用带有通讯录的发送界面,以及模板功能等方便性功能操作,如下所示。

通讯录可以通过调用窗体函数进行数据绑定,这样在调用的时候,只需要按照要求填写相应的数据就可以显示个人专属的通讯录了,方便勾选手机进行发送短信,操作绑定代码如下所示。

private void btnSendWithList_Click(object sender, EventArgs e)
{
FrmSendSMSWithList dlg = new FrmSendSMSWithList();
Dictionary<string, List<ContactInfo>> dict = new Dictionary<string,List<ContactInfo>>();
List<ContactInfo> list = new List<ContactInfo>();
string category = "个人通讯录";
list.Add(new ContactInfo(category, "
    
[3]WPF:把Task, Lazy<T>和INotifyPropertyChanged组装成一个超级属性
    来源:    发布时间: 2013-10-28

这三个元素,Task代表着异步多线程,Lazy<T>代表着延迟初始化,INotifyPropertyChanged则代表着属性改变通知(多用于MVVM模式中)。那么如果把这三个元素组合起来就是一个异步延迟初始化的INotifyPropertyChanged属性。

 

实现起来是这样,因为Task和Lazy<T>只针对方法,而INotifyPropertyChanged只针对属性。所以异步延迟初始化的INotifyPropertyChanged属性还需要一个属性的初始化值,整个过程很简单。当第一次尝试获取属性值之后,初始值会被立刻返回,接着Task运行,注意此时无论多少个线程同时获取属性值,只有一个Task会运行(这是Lazy<T>的功劳),最终等这个Task运行结束后,属性值改变,通过INotifyPropertyChanged接口的执行来反馈给需要属性地方(比如界面上的数据绑定)。

 

这里我先对其他两两组合的情况讨论一下,当然相比把这三个一起组合起来,两两组合实现起来更简单些:

Task Lazy<T> 可以参考.NET Parallel Programming博客中的AsyncLazy<T>实现。 INotifyPropertyChanged Task 和没有TPL时的原始多线程操作一样,只不过需要注意操作结束后要在当前SynchronizationContext中执行属性的设置操作(因为属性改变会诱发UI改变,而UI改变必须在UI线程内)。
这里推荐用C# 5.0的async/await。 Lazy<T> INotifyPropertyChanged 没有太大意义,因为Lazy<T>的值是不可改变的。如果界面绑定的话,直接绑定Lazy<T>的Value属性。

 

下面讲我们这个三个组合的,运行示例程序可以看到,起初界面绑定的都是初始值(此时背后的Task已经开始运行),同时整个属性还提供是否加载完毕和有错误的信息(这些属性也是INotifyPropertyChanged执行的),在最下方有两个按钮又绑定了同样的属性值,但实际上异步延迟初始化只进行一次:

几秒后,Task运行完毕,界面发生了变化,属性1返回结果,属性2抛出异常,界面上会显示异常信息同时属性2的值保持初始值:

整个过程界面都是响应的,也就是说操作是异步的。

 

属性的类型名称是AsyncProperty,是在AsyncLazy<T>的基础上,加入了初始值和INotifyPropertyChanged的支持:

 

不过AsyncProperty<T>没有像AsyncLazy<T>那样以Lazy<Task<T>>为父类,而是把Lazy<Task<T>>作为一个字段,这样在初始化时更好被处理。用户可以通过Func<T>或者返回Task的Func<Task<T>>来初始化AsyncProperty类型。

AsyncValue属性是AsyncProperty的值,当第一次获取AsyncValue属性,它会立刻返回初始值,接着运行背后Task,当Task结束后,AsyncValue的属性会再次改变。

Error属性是错误信息,当Task中的代码发生异常后,Error会返回异常也就是Exception的Message属性。

HasValue和HasError代表是否又值和是否有错误。当HasError为True后HasValue也会是True,这里HasValue有点像是否完成初始化的意思。

(上述属性全是执行INotifyPropertyChanged接口)

 

AsyncProperty的使用就是这样很简单,那么示例程序中的ViewModel就是这样初始化AsyncProperty的:

public class ViewModel

{

    public AsyncProperty<string> Data1 { get; private set; }

    public AsyncProperty<int> Data2 { get; private set; }

 

    public ViewModel()

    {

        //注意是返回Task的委托,而不是直接运行的Task

        var task1 = new Func<Task<string>>(() => Task.Run(() =>

            {

                Task.Delay(3000).Wait();

                return "Mgen";

            }));

        var task2 = new Func<Task<int>>(() => Task.Run(()

    
最新技术文章:
 




特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3