zoukankan      html  css  js  c++  java
  • 信息系统开发平台OpenExpressApp - 支持勾选视图

      在OpenExpressApp部门+岗位=角色,功能权限属于角色的,所以功能权限也放在部门模块中设置了,后期将会单独对权限部门进行介绍,本篇讲解一下在功能权限实现中使用到的一种新的内置视图样式,我把它叫做勾选视图

    之前的列表视图

      OEA的所有Command都有一个Guid,角色下功能权限下存储的实际上是不能使用的功能的Guid,如果按照以往来实现,界面如下:

      界面左边为模块,右边为分组的对象功能列表,这时可以通过设计一个【选择】功能,弹出一个对话框,对话框显示所有模块的所有对象功能列表,然后通过选择后加入细表。虽然这样可以很方便的使用以前框架的功能来实现,但是用户使用起来会很不方便。这种方式,勾选一个功能需要需要点击弹出对话框,然后选择一些内容,然后关闭。而系统模块功能可能很多,这样操作就会让用户点击按钮多次。  

    新增的勾选视图

      勾选视图界面显示如上图所示,右边把原来弹出的对话框内容显示在这里,前面加了一个checkbox框提供选择,通过勾选操作来实现以往的选择功能。现在用户新增或者去除一个功能,只需要勾选一次就可以解决,而以往操作需要3个步骤。

      之前项目任务中就遇到过类似操作,当时就想实现一个通用视图来提高易用性,不过由于时间原因没有做,直到今天才完成。下面介绍一下勾选视图的主要实现和使用。

    为了下面讲解时对数据说明清楚,定义一下两个术语:

      源数据:勾选的列表,相当于以前弹出选择框的数据

          目的数据:操作的对象列表,通过勾选操作影响到的实际对象

    实现要求

    1. 由于这只是操作样式不一样,所以我不希望在以前的业务对象类库里加入这部分功能 ,这部分功能与类库隔离开来
    2. 把这个功能抽象为一中通用的样式视图,通过一些属性设置和约定来实现
    3. 延用以前框架代码,在之前框架代码上扩展

    框架内部实现

    • UI
      勾选列表是一个列表视图,所以可以重用以前的ListObjectView,只是需要增加一个checkbox列。现在实现为通过附加属性来实现
      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);
      }
      }
      }
    • 数据
      以前UI显示的数据是父对象的子对象列表属性(目的数据),现在需要显示为源数据,则需要修改LoadData,
      /// <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);
      }
      }
      对于通过本地导航获取数据的,需要修改FilterData
      /// <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);
      }
      }
    • 操作
      勾选时需要触发增加或者删除目的数据对象,通过在给View的Data赋值时遍历源数据每条记录的INotifyPropertyChanged事件来处理  
    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);
    }
    }
    };
    }

    外部开发使用

    • 设置Association属性

    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属性中设置三个属性:

    1. AssociationOperateType = AssociationOperateType.Selected
      关联操作类型,设置为Selected表示使用勾选视图,如果你把值设置为Self,或者不设置此值,那么显示结果就切换到最上面那个图了
    2. IsForwardSelected =false
      决定勾选check值触发添加记录还是删除记录,如果为true,表示正向操作,勾选时则新增对象,去除勾选时则删除对象,如果为false,则相反
    3. SelectedPropertyMap = "BusinessObjectId;OperationId"
      在勾选操作导致新增对象时,需要给新增对象的一些属性赋值,这些属性值来源于选择列表对象的属性,通过这个属性来映射。格式为:列表属性1=子对象属性1;列表属性2=子对象属性2,如果没有=号,表示两个属性名称相同
    • 实现选择适配类

    选择类如下,同以往业务类类似,属性比以往弹出选择列表对象类相似,唯一差别就是增加了一个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); }
    }
    ...
    }
    • GetList_Selected方法

      当系统从AssociationOperateType获知是勾选视图时,系统通过约定的一个方法GetList_Selected来获取源数据,如果有导航则通过方法参数来匹配导航类,参考代码如下: 

    /// <summary>
    /// 采用选择操作对象模式时, 选择列表过滤后数据, 匹配LocalFilter
    /// </summary>
    /// <param name="criteria"></param>
    /// <returns></returns>
    public BoInfoOperationSelectedList GetList_Selected(OrgPositionOperationCriteria criteria)
    {
    return BoInfoOperationSelectedList.GetAggregationteList(criteria.BusinessObjectInfo);
    }


    更多内容: 开源信息系统开发平台之OpenExpressApp框架.pdf

  • 相关阅读:
    Vue学习手记01-安装和项目创建
    [Powershell] FTP Download File
    [PowerShell] Backup Folder and Files Across Network
    SSRS 请求并显示SharePoint人员和组字段
    Beta 冲刺 (2/7)
    Beta 冲刺 (1/7)
    BETA 版冲刺前准备
    事后诸葛亮
    Alpha 答辩总结
    α冲刺 (10/10)
  • 原文地址:https://www.cnblogs.com/zhoujg/p/1639094.html
Copyright © 2011-2022 走看看