天天看點

資訊系統開發平台OpenExpressApp - 支援勾選視圖

  OEA的所有Command都有一個Guid,角色下功能權限下存儲的實際上是不能使用的功能的Guid,如果按照以往來實作,界面如下:

  界面左邊為子產品,右邊為分組的對象功能清單,這時可以通過設計一個【選擇】功能,彈出一個對話框,對話框顯示所有子產品的所有對象功能清單,然後通過選擇後加入細表。雖然這樣可以很友善的使用以前架構的功能來實作,但是使用者使用起來會很不友善。這種方式,勾選一個功能需要需要點選彈出對話框,然後選擇一些内容,然後關閉。而系統子產品功能可能很多,這樣操作就會讓使用者點選按鈕多次。  

<b>  勾選視圖</b>界面顯示如上圖所示,右邊把原來彈出的對話框内容顯示在這裡,前面加了一個checkbox框提供選擇,通過勾選操作來實作以往的選擇功能。現在使用者新增或者去除一個功能,隻需要勾選一次就可以解決,而以往操作需要3個步驟。

  之前項目任務中就遇到過類似操作,當時就想實作一個通用視圖來提高易用性,不過由于時間原因沒有做,直到今天才完成。下面介紹一下勾選視圖的主要實作和使用。

<b>為了下面講解時對資料說明清楚,定義一下兩個術語:</b>

  <b>源資料</b>:勾選的清單,相當于以前彈出選擇框的資料

      <b>目的資料</b>:操作的對象清單,通過勾選操作影響到的實際對象

由于這隻是操作樣式不一樣,是以我不希望在以前的業務對象類庫裡加入這部分功能 ,這部分功能與類庫隔離開來

把這個功能抽象為一中通用的樣式視圖,通過一些屬性設定和約定來實作

延用以前架構代碼,在之前架構代碼上擴充

UI

勾選清單是一個清單視圖,是以可以重用以前的ListObjectView,隻是需要增加一個checkbox列。現在實作為通過附加屬性來實作

public static readonly DependencyProperty IsCheckedProperty =

DependencyProperty.RegisterAttached("IsChecked", typeof(bool), typeof(SelectedDataAttached),

new FrameworkPropertyMetadata(new PropertyChangedCallback(OnIsCheckedChanged)));

/// &lt;summary&gt;

/// Handles changes to the IsChecked property.

/// &lt;/summary&gt;

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) &amp;&amp; ((string)grid.Columns[0].Header == "選擇"))

grid.Columns.RemoveAt(0);

資料

以前UI顯示的資料是父對象的子對象清單屬性(目的資料),現在需要顯示為源資料,則需要修改LoadData,

/// 裝載資料,考慮(AssociationOperateType.Selected

public override void LoadData()

base.LoadData();

if ((AllowLoadData) &amp;&amp; (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

/// 導航過濾資料

/// &lt;param name="queryObject"&gt;&lt;/param&gt;

public void FilterData(IQueryObject queryObject)

_data = this.Parent.CurrentObject.GetPropertyValue(PropertyName);

if (AssociationOperateType.Self == BOsPropInfo.AssociationAttribute.AssociationOperateType)

Data = obj.CallMethod(MethodConvention.GetList, queryObject);

Data = obj.CallMethod(MethodConvention.GetList_Selected, queryObject);

_destData = obj.CallMethod(MethodConvention.GetList, queryObject);

操作

勾選時需要觸發增加或者删除目的資料對象,通過在給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);

DeleteObject(sender, destData, view);

else //反向

};

<b>設定Association屬性</b>

private static PropertyInfo&lt;OrgPositionOperations&gt; OrgPositionOperationsProperty =

RegisterProperty(new PropertyInfo&lt;OrgPositionOperations&gt;("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屬性中設定三個屬性:

AssociationOperateType = AssociationOperateType.Selected

關聯操作類型,設定為Selected表示使用勾選視圖,如果你把值設定為Self,或者不設定此值,那麼顯示結果就切換到最上面那個圖了

IsForwardSelected =false

決定勾選check值觸發添加記錄還是删除記錄,如果為true,表示正向操作,勾選時則新增對象,去除勾選時則删除對象,如果為false,則相反

SelectedPropertyMap = "BusinessObjectId;OperationId"

在勾選操作導緻新增對象時,需要給新增對象的一些屬性指派,這些屬性值來源于選擇清單對象的屬性,通過這個屬性來映射。格式為:清單屬性1=子對象屬性1;清單屬性2=子對象屬性2,如果沒有=号,表示兩個屬性名稱相同

<b>實作選擇适配類</b>

選擇類如下,同以往業務類類似,屬性比以往彈出選擇清單對象類相似,唯一差别就是增加了一個IsSelected屬性,參考代碼如下:

public partial class BoInfoOperationSelectedList : GBusinessListBase&lt;BoInfoOperationSelectedList, BoInfoOperationSelected&gt;

{... }

[Serializable]

[BusinessObject("2F1C87E1-8067-49b5-918C-230038AFA1F7", PropertyGroup = "ObjectName"), Label("對象功能")]

public partial class BoInfoOperationSelected : GBusinessBase&lt;BoInfoOperationSelected&gt;

...

private static PropertyInfo&lt;bool&gt; IsSelectedProperty =

RegisterProperty(new PropertyInfo&lt;bool&gt;("IsSelected"));

[EntityProperty]

[ShowInList, Label("選擇"), ShowInLookup]

public bool IsSelected

get { return GetProperty(IsSelectedProperty); }

set { SetProperty(IsSelectedProperty, value); }

<b>GetList_Selected方法</b>

  當系統從AssociationOperateType獲知是勾選視圖時,系統通過約定的一個方法<b>GetList_Selected</b>來擷取源資料,如果有導航則通過方法參數來比對導航類,參考代碼如下: 

/// 采用選擇操作對象模式時, 選擇清單過濾後資料, 比對LocalFilter

/// &lt;param name="criteria"&gt;&lt;/param&gt;

/// &lt;returns&gt;&lt;/returns&gt;

public BoInfoOperationSelectedList GetList_Selected(OrgPositionOperationCriteria criteria)

return BoInfoOperationSelectedList.GetAggregationteList(criteria.BusinessObjectInfo);

本文轉自 jingen_zhou 51CTO部落格,原文連結:http://blog.51cto.com/zhoujg/518661,如需轉載請自行聯系原作者