XAF之自定义登录窗口
来源:互联网 发布:圣贝口腔 知乎 编辑:程序博客网 时间:2024/04/29 16:59
当使用Standard Authentication验证类型,默认的登录窗口包含两个编辑框:用户名和密码。而本文讲述怎样自定义登录窗口,窗口包含一个下拉式列表选择company,另一个下拉式列表选择该company的employee,还有一个密码输入框。
自定义登录窗口,有以下两种方法:
a.继承AuthenticationStandardLogonParameters类,添加要在登录窗显示的额外属性。然后,可以用安全系统的LogonParameters属性访问特定的登录参数。然而,验证机制仍只使用用户名和密码。所以,若要对额外属性进行验证,需要继承AuthenticationStandard类并重写Authenticate方法。别忘了在Application Designer中指定自定义的登录参数类:
b.实现一个LogonParameters类(不从AuthenticationStandardLogonParameters类继承),添加额外属性。这种情况下,内置的AuthenticationStandard无法执行验证,所以还必须实现自定义的验证策略:继承AuthenticationBase类。
这里,我们使用第二种方法。
实现Employee和Company类
由于Employee必须支持安全系统,故需要继承BasicUser类。
using System;using System.Collections.Generic;using System.Text;using DevExpress.Persistent.BaseImpl;using DevExpress.Xpo;using DevExpress.Persistent.Base;using DevExpress.ExpressApp.Utils;using DevExpress.Data.Filtering;using System.ComponentModel;namespace AccessDatabaseFromLogonForm.Module { [DefaultClassOptions(), System.ComponentModel.DefaultProperty("UserName")]public class Employee : SimpleUser {private Company company; public Employee(Session session) : base(session) { } [Association("Company-Employees", typeof(Company))] public Company Company { get { return company; }set {SetPropertyValue("Company", ref company, value);} } }}
using System;using DevExpress.Data.Filtering;using DevExpress.Xpo;using DevExpress.ExpressApp;using DevExpress.Persistent.Base;using DevExpress.Persistent.BaseImpl;using DevExpress.Persistent.Validation;using DevExpress.ExpressApp.Utils;namespace AccessDatabaseFromLogonForm.Module { [DefaultClassOptions()] public class Company : BaseObject { public Company(Session session) : base(session) { } private string name; public string Name { get { return name; }set {SetPropertyValue("Name", ref name, value);} } [Association("Company-Employees", typeof(Employee))] public XPCollection Employees { get { return GetCollection("Employees"); } } }}实现MyLogonParameters类
//实现ISupportResetLogonParameters接口,不必重启程序实现登录和注销 //在persistent类中,可以在属性setter中使用SetPropertyValue或OnChanged,但MyLogonParameters不是 //从BaseObject继承而来,故只能实现INotifyPropertyChanged接口[NonPersistent]public class MyLogonParameters : INotifyPropertyChanged, ISupportResetLogonParameters { private IObjectSpace objectSpace; //为避免在登录窗口新建Employee和Company,需要设置AvailableCompanies和AvailableUsers只读 private ReadOnlyCollection<Company> availableCompanies; private XPCollection<Employee> availableUsers; private Company company; private Employee employee; private string password; private void OnPropertyChanged(string propertyName) { if(PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } //显示的Employee要对于其Company,故为availableUsers添加了一个Criteria private void RefreshAvailableUsers() { if(availableUsers == null) { return; } availableUsers.Criteria = new BinaryOperator("Company", Company); if(employee != null && availableUsers.IndexOf(employee) == -1) { Employee = null; } else { OnPropertyChanged("Employee"); } } [Browsable(false)] public IObjectSpace ObjectSpace { get { return objectSpace; } set { objectSpace = value; } } //设置为ReadOnlyCollection,只读集合 [Browsable(false)] public ReadOnlyCollection<Company> AvailableCompanies { get { if (objectSpace == null) { throw new InvalidOperationException("objectSpace is null"); } if (availableCompanies == null) {availableCompanies = new ReadOnlyCollection<Company>(ObjectSpace.GetObjects<Company>(null));} return availableCompanies; } } [Browsable(false)] public XPCollection<Employee> AvailableUsers { get { if (availableUsers == null) {availableUsers = (XPCollection<Employee>)ObjectSpace.GetObjects<Employee>(); //设置availableUsers只读,不允许绑定的control增/删数据 availableUsers.BindingBehavior = CollectionBindingBehavior.AllowNone; RefreshAvailableUsers(); } return availableUsers; } } //DataSourceProperty表示Company依赖于于属性AvailableCompanies,非常类似于PersistentAlias特性 //但PersistentAlias是对属性的高级”重命名“,DataSourceProperty是属性和数据绑定的关系 //ImmediatePostData表示当Company数据变化后,立即刷新UI [DataSourceProperty("AvailableCompanies"), ImmediatePostData] public Company Company { get { return company; } set { company = value; RefreshAvailableUsers(); } }[DataSourceProperty("AvailableUsers"), ImmediatePostData] public Employee Employee { get { return employee; } set { employee = value; OnPropertyChanged("Employee"); } } [PasswordPropertyText(true)] public string Password { get { return password; } set { password = value; } } public void Reset() { objectSpace = null; availableCompanies = null; availableUsers = null; company = null; employee = null; password = null; } public event PropertyChangedEventHandler PropertyChanged; }
在Program.cs 文件中创建AvailableUsers 和 AvailableCompanies 的ObjectSpaced,并订阅CreateCustomLogonWindowObjectSpace事件
static void Main() {//...AccessDatabaseFromLogonFormWindowsFormsApplication application =new AccessDatabaseFromLogonFormWindowsFormsApplication();application.CreateCustomLogonWindowObjectSpace +=new EventHandler<CreateCustomLogonWindowObjectSpaceEventArgs>(application_CreateCustomLogonWindowObjectSpace);//...}static void application_CreateCustomLogonWindowObjectSpace(object sender,CreateCustomLogonWindowObjectSpaceEventArgs e) {e.ObjectSpace = ((XafApplication)sender).CreateObjectSpace();((MyLogonParameters)e.LogonParameters).ObjectSpace = e.ObjectSpace;}
实现MyAuthentication类
继承AuthenticationBase类,并重写以下方法:
Authenticate
验证时调用。验证时比对数据库里的信息和logon parameter的值。
ClearSecuredLogonParameters
清除logon parameters,防止在程序里访问它们,这样就隐藏了安全信息。
GetBusinessClasses
返回要添加到Application Model 中的bussiness classese。如果不返回LogonParameters,则不会在登录窗口中显示该视图。
AskLogonParametersViaUI
如果需要显示登录窗口获取用户的logon parameters,则返回true。若从其他地方获取logon parameters,如系统活动文件夹,则返回false。
LogonParameters
返回代表当前logon parameters的对象。
IsLogoffEnabled
是否允许“注销”操作。当前仅在ASP.NET可用。
public class MyAuthentication : AuthenticationBase, IAuthenticationStandard {private MyLogonParameters logonParameters; //创建一个LogonParameters对象public MyAuthentication() {logonParameters = new MyLogonParameters();} //清除登录信息public override void ClearSecuredLogonParameters() {logonParameters.Password = "";base.ClearSecuredLogonParameters();} //验证登录,正确则返回该登录用户public override object Authenticate(DevExpress.ExpressApp.IObjectSpace objectSpace) {if(logonParameters.Employee == null) {throw new ArgumentNullException("User");} //比对密码if(!logonParameters.Employee.ComparePassword(logonParameters.Password)){ throw new AuthenticationException(logonParameters.Employee.UserName, "Wrong password");}return objectSpace.GetObject(logonParameters.Employee);}public override IList<Type> GetBusinessClasses() {return new Type[] { typeof(MyLogonParameters) };}public override bool AskLogonParametersViaUI {get {return true;}}public override object LogonParameters {get { return logonParameters; }}public override bool IsLogoffEnabled {get { return true; }}}将自定义的这些类传递给系统
在Application Designer 中,只能添加内置的AuthenticationStandard策略,所以只能在代码中添加MyAuthentication类。WinForm工程里的Main方法中添加:
AccessDatabaseFromLogonFormWindowsFormsApplication application =new AccessDatabaseFromLogonFormWindowsFormsApplication();application.Security = new SecuritySimple<Employee>(new MyAuthentication());
- XAF之自定义登录窗口
- XAF之自定义Function Criteria Operator
- XAF之点击Navigation Control弹出新建对象窗口
- XAF之Action
- XAF之Security System
- XAF之ObjectSpace
- XAF之Templates Customization
- XAF之弹出式进度条
- XAF之PropertyEditor
- XAF之Dashboard
- XAF之DashboardViewItem管理
- XAF之SplashScreenManager
- XAF之Servermode注意
- xaf实现自定义只读参数
- XAF学习二:在XAF中打开自定义的WinForm
- XAF之创建条件外观
- XAF之常用的CriteriaOperator
- XAF之Frame和Controller
- 关于Android中的Context
- 学习OpenCV——鼠标事件 输出鼠标坐标&区域亮化
- 入门视频采集与处理(显示YUV数据)
- CvSeq动态结构序列
- Delphi 回调函数 线程
- XAF之自定义登录窗口
- jquery手册学习--属性--attr(name|pro|key,val|fn) --removeAttr(name)
- pentaho Dashboards Editor (CDE) 仪表盘布局
- 聚簇
- iptables
- document.execcommand方法
- SQL语句中case语句语法学习
- 哈夫曼(Huffman)树与哈夫曼编码
- C++0x:如何获取lambda表达式的返回类型