在OpenExpressApp中部门+岗位=角色,功能权限属于角色的,所以功能权限也放在部门模块中设置了,后期将会单独对权限部门进行介绍,本篇讲解一下在功能权限实现中使用到的一种新的内置视图样式,我把它叫做勾选视图。
OEA的所有Command都有一个Guid,角色下功能权限下存储的实际上是不能使用的功能的Guid,如果按照以往来实现,界面如下:
界面左边为模块,右边为分组的对象功能列表,这时可以通过设计一个【选择】功能,弹出一个对话框,对话框显示所有模块的所有对象功能列表,然后通过选择后加入细表。虽然这样可以很方便的使用以前框架的功能来实现,但是用户使用起来会很不方便。这种方式,勾选一个功能需要需要点击弹出对话框,然后选择一些内容,然后关闭。而系统模块功能可能很多,这样操作就会让用户点击按钮多次。
勾选视图界面显示如上图所示,右边把原来弹出的对话框内容显示在这里,前面加了一个checkbox框提供选择,通过勾选操作来实现以往的选择功能。现在用户新增或者去除一个功能,只需要勾选一次就可以解决,而以往操作需要3个步骤。
之前项目任务中就遇到过类似操作,当时就想实现一个通用视图来提高易用性,不过由于时间原因没有做,直到今天才完成。下面介绍一下勾选视图的主要实现和使用。
为了下面讲解时对数据说明清楚,定义一下两个术语:
源数据:勾选的列表,相当于以前弹出选择框的数据
目的数据:操作的对象列表,通过勾选操作影响到的实际对象
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.RegisterAttached( " IsChecked " , typeof ( bool ), typeof (SelectedDataAttached),
new FrameworkPropertyMetadata( new PropertyChangedCallback(OnIsCheckedChanged)));
/// <summary>
/// Handles changes to the IsChecked property.
/// </summary>
private static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DataGrid)
{
DataGrid grid = d as DataGrid;
if (( bool )e.NewValue)
{
DataGridCheckBoxColumn column = new DataGridCheckBoxColumn() { Header = " 选择 " };
column.Binding = new Binding(PropertyConvention.IsSelected);
grid.Columns.Insert( 0 , column);
}
else
{
if ((grid.Columns[ 0 ] is DataGridCheckBoxColumn) && (( string )grid.Columns[ 0 ].Header == " 选择 " ))
grid.Columns.RemoveAt( 0 );
}
}
}
/// <summary>
/// 装载数据,考虑(AssociationOperateType.Selected
/// </summary>
public override void LoadData()
{
base .LoadData();
if ((AllowLoadData) && (AssociationOperateType.Selected == BOsPropInfo.AssociationAttribute.AssociationOperateType))
{
LateBoundObject obj = new LateBoundObject(_data);
Data = obj.CallMethod(MethodConvention.GetList_Selected);
_destData = this .Parent.CurrentObject.GetPropertyValue(PropertyName);
(Control as UIElement).SetValue(SelectedDataAttached.DestDataProperty, _destData);
}
}
/// <summary>
/// 导航过滤数据
/// </summary>
/// <param name="queryObject"></param>
public void FilterData(IQueryObject queryObject)
{
_data = this .Parent.CurrentObject.GetPropertyValue(PropertyName);
LateBoundObject obj = new LateBoundObject(_data);
if (AssociationOperateType.Self == BOsPropInfo.AssociationAttribute.AssociationOperateType)
Data = obj.CallMethod(MethodConvention.GetList, queryObject);
else
{
Data = obj.CallMethod(MethodConvention.GetList_Selected, queryObject);
_destData = obj.CallMethod(MethodConvention.GetList, queryObject);
(Control as UIElement).SetValue(SelectedDataAttached.DestDataProperty, _destData);
}
}
foreach (var srcItem in srcData)
{
// 属性更改触发新增删除对象
(srcItem as INotifyPropertyChanged).PropertyChanged += delegate ( object sender, PropertyChangedEventArgs pe)
{
if (pe.PropertyName.ToLower() == PropertyConvention.IsSelected.ToLower())
{
bool isSelected = ( bool )sender.GetPropertyValue(PropertyConvention.IsSelected);
if (view.BOsPropInfo.AssociationAttribute.IsForwardSelected) // 正向
{
if (isSelected)
AddObject(sender, destData, view);
else
DeleteObject(sender, destData, view);
}
else // 反向
{
if (isSelected)
DeleteObject(sender, destData, view);
else
AddObject(sender, destData, view);
}
}
};
}
private static PropertyInfo < OrgPositionOperations > OrgPositionOperationsProperty =
RegisterProperty( new PropertyInfo < OrgPositionOperations > ( " OrgPositionOperations " ));
[Association(AssociationOperateType = AssociationOperateType.Selected, IsForwardSelected =false , SelectedPropertyMap = " BusinessObjectId;OperationId " )]
public OrgPositionOperations OrgPositionOperations
{
get
{
if ( ! FieldManager.FieldExists(OrgPositionOperationsProperty))
{
LoadProperty(OrgPositionOperationsProperty, OrgPositionOperations.NewChild());
}
return GetProperty(OrgPositionOperationsProperty);
}
}
在Association属性中设置三个属性:
选择类如下,同以往业务类类似,属性比以往弹出选择列表对象类相似,唯一差别就是增加了一个IsSelected属性,参考代码如下:
public partial class BoInfoOperationSelectedList : GBusinessListBase < BoInfoOperationSelectedList, BoInfoOperationSelected >
{... }
[Serializable]
[BusinessObject( " 2F1C87E1-8067-49b5-918C-230038AFA1F7 " , PropertyGroup = " ObjectName " ), Label( " 对象功能 " )]
public partial class BoInfoOperationSelected : GBusinessBase < BoInfoOperationSelected >
{
...
private static PropertyInfo < bool > IsSelectedProperty =
RegisterProperty( new PropertyInfo < bool > ( " IsSelected " ));
[EntityProperty]
[ShowInList, Label( " 选择 " ), ShowInLookup]
public bool IsSelected
{
get { return GetProperty(IsSelectedProperty); }
set { SetProperty(IsSelectedProperty, value); }
}
...
}
当系统从AssociationOperateType获知是勾选视图时,系统通过约定的一个方法GetList_Selected来获取源数据,如果有导航则通过方法参数来匹配导航类,参考代码如下:
/// <summary>
/// 采用选择操作对象模式时, 选择列表过滤后数据, 匹配LocalFilter
/// </summary>
/// <param name="criteria"></param>
/// <returns></returns>
public BoInfoOperationSelectedList GetList_Selected(OrgPositionOperationCriteria criteria)
{
return BoInfoOperationSelectedList.GetAggregationteList(criteria.BusinessObjectInfo);
}