在Winform開發中,我們使用的幾種下拉選單展示字典資料的方式

2022-09-23 12:01:05

在Winform開發中中,我們為了方便客戶選擇,往往使用系統的字典資料選擇,畢竟選擇總比輸入來的快捷、統一,一般我們都會簡單封裝一下,以便方便對控制元件的字典值進行展示處理,本篇隨筆介紹DevExpress控制元件的幾種常見的字典繫結展示方式,希望我們在實際WInform專案中使用到。

1、常規下拉選單的處理

常規的處理方式,可能會使用ComboBoxEdit 控制元件來承載下拉選單,下拉選單的值可以是固定的列表,也可以來自字典的方式,具體根據實際情況而定,大概的效果如下所示。

 單擊下拉選單,會展示一些常規的字典專案,如下效果所示。

 如果使用控制元件原始方式,我們繫結控制元件的下拉選單值的做法如下所示。

combo.Properties.BeginUpdate();//可以加快
combo.Properties.Items.Clear();
combo.Properties.Items.AddRange(itemList);
combo.Properties.EndUpdate();//可以加快

不過我們一般傾向於高效率的介面處理,一般會編寫各型別的介面控制元件的擴充套件函數用於快速處理。

不同型別的控制元件我們用一個獨立的擴充套件檔案來處理,這樣方便維護的同時,也方便借鑑完善。

例如對於上面的控制元件,我們的繫結方法的擴充套件函數如下所示。

/// <summary>
/// 繫結下拉選單控制元件為指定的資料字典列表
/// </summary>
/// <param name="combo">下拉選單控制元件</param>
/// <param name="itemList">資料字典列表</param>
/// <param name="defaultValue">控制元件預設值</param>
/// <param name="emptyFlag">是否加入空值選項</param>
public static void BindDictItems(this ComboBoxEdit combo, List<CListItem> itemList, string defaultValue, bool emptyFlag = true)
{
    combo.Properties.BeginUpdate();//可以加快
    combo.Properties.Items.Clear();
    combo.Properties.Items.AddRange(itemList);
    if (emptyFlag)
    {
        combo.Properties.Items.Insert(0, new CListItem(""));
    }

    if (itemList.Count > 0)
    {
        if (!string.IsNullOrEmpty(defaultValue))
        {
            combo.SetComboBoxItem(defaultValue);
        }
        else
        {
            combo.SelectedIndex = 0;
        }
    }

    combo.Properties.EndUpdate();//可以加快
}

其中方法增加了一些預設值以及是否追加空白專案的處理。

當然,我們為了適應各種資料來源的繫結方式,我們過載了很多不同的函數處理,如下截圖所示。

 當然對於其他同型別的下列列表控制元件也是這樣處理即可。這樣介面上,我們就可以指定呼叫繫結的處理操作了

private void InitDictItem()
{
    this.txtManufacture.Items.Clear();
    this.txtManufacture.Items.AddRange(DictItemUtil.GetDictByDictType("供貨商"));

    this.txtBigType.Items.Clear();
    this.txtBigType.Items.AddRange(DictItemUtil.GetDictByDictType("備件屬類"));
} 

或者,我們可以根據字典的型別,來進一步做一個擴充套件函數,來簡化繫結的處理。

/// <summary>
/// 繫結下拉選單控制元件為指定的資料字典列表
/// </summary>
/// <param name="control">下拉選單控制元件</param>
/// <param name="dictTypeName">資料字典型別名稱</param>
/// <param name="defaultValue">控制元件預設值</param>
/// <param name="emptyFlag">是否新增空行</param>
public static void BindDictItems(this ComboBoxEdit control, string dictTypeName, string defaultValue, bool emptyFlag = true)
{
    Dictionary<string, string> dict = BLLFactory<DictData>.Instance.GetDictByDictType(dictTypeName);
    List<CListItem> itemList = new List<CListItem>();
    foreach (string key in dict.Keys)
    {
        itemList.Add(new CListItem(key, dict[key]));
    }

    control.BindDictItems(itemList, defaultValue, emptyFlag);
}

使用了這些簡化的擴充套件函數,我們可以對系統的字典,根據字典型別來進行繫結了。

private void InitDictItem()
{
    this.txtManufacture.BindDictItems("供貨商");
    this.txtSearchManufacture.BindDictItems("供貨商");
    this.txtSearchDept.BindDictItems("部門");
}

如上程式碼所示,簡化了很多處理,就一個函數就可以繫結了系統字典型別的下拉選單了。

2、帶序號的GridLookUpEdit下拉選單

有時候,我們在一些常見的系統裡面,經常看到一些帶有序號的下拉選單,其實裡面就是一個GridControl的控制元件,我們只需要賦值對應的列表資料來源,以及設定顯示的列內容,並重寫下序號的展示處理就可以實現了。

我們先來看看實際的效果。

上面的列表是一個GridControl的內在控制元件,我們使用這個 GridLookUpEdit下拉選單控制元件的時候,設定好GridControl的資料來源和顯示的列就基本上可以了。

//繫結資料來源和顯示的內容、隱藏值
this.txtProjectList.Properties.DataSource = list;
this.txtProjectList.Properties.ValueMember = "Value";
this.txtProjectList.Properties.DisplayMember = "Text";

//設定Grid顯示的列資訊
var columns = new List<LookUpColumnInfo>()
{
    new LookUpColumnInfo("Value", "顯示名稱")
};
for (int i = 0; i < columns.Count; i++)
{
    this.txtProjectList.Properties.View.CreateColumn(columns[i].FieldName, columns[i].Caption,
        columns[i].Width, true, UnboundColumnType.Bound, DefaultBoolean.False, FixedStyle.None);
}

//其他屬性設定
this.txtProjectList.Properties.ImmediatePopup = true;
this.txtProjectList.Properties.TextEditStyle = TextEditStyles.Standard;
this.txtProjectList.Properties.PopupWidthMode = DevExpress.XtraEditors.PopupWidthMode.ContentWidth;

//設定列表的序號的寬度和顯示文字
this.txtProjectList.Properties.View.IndicatorWidth = 40;
this.txtProjectList.Properties.View.CustomDrawRowIndicator += (s, e) =>
{
    if (e.Info.IsRowIndicator && e.RowHandle >= 0)
    {
        e.Info.DisplayText = (e.RowHandle + 1).ToString();
    }
};

 那麼如果我們需要使用擴充套件函數來簡化實際的程式碼,那麼應該如何封裝這個GridLookupEdit的下列控制元件呢,我們編寫的擴充套件函數程式碼如下所示。

        /// <summary>
        /// 繫結控制元件的資料來源
        /// </summary>
        /// <param name="lookup">控制元件物件</param>
        /// <param name="dataSource">資料來源</param>
        /// <param name="displayMember">顯示欄位</param>
        /// <param name="valueMember">值欄位</param>
        /// <param name="showRowIndicator">是否顯示序號</param>
        /// <param name="lookUpColumnInfos">顯示的列</param>
        /// <returns></returns>
        public static object BindDictItems(this GridLookUpEdit lookup, object dataSource, string displayMember, string valueMember, bool showRowIndicator = true, params LookUpColumnInfo[] lookUpColumnInfos)
        {
            lookup.Properties.DataSource = dataSource;
            lookup.Properties.DisplayMember = displayMember;
            lookup.Properties.ValueMember = valueMember;

            lookup.Properties.View.Columns.Clear();
            for (int i = 0; i < lookUpColumnInfos.Length; i++)
            {
                lookup.Properties.View.CreateColumn(lookUpColumnInfos[i].FieldName, lookUpColumnInfos[i].Caption,
                    lookUpColumnInfos[i].Width, true, UnboundColumnType.Bound, DefaultBoolean.False, FixedStyle.None);
            }
            lookup.Properties.ImmediatePopup = true;
            lookup.Properties.TextEditStyle = TextEditStyles.Standard;

            if (showRowIndicator)
            {
                lookup.Properties.View.IndicatorWidth = 40;
                //重寫序號顯示,預設不顯示數值
                lookup.Properties.View.CustomDrawRowIndicator += (s, e) =>
                {
                    if (e.Info.IsRowIndicator && e.RowHandle >= 0)
                    {
                        e.Info.DisplayText = (e.RowHandle + 1).ToString();
                    }
                };
            }

            return dataSource;
        }

這樣處理後,介面上簡化了不少程式碼,如下使用程式碼所示。

var list = DictItemUtil.GetDictByDictType("備件類別");
var columns = new List<LookUpColumnInfo>()
{
    new LookUpColumnInfo("Value", "顯示名稱")
};

this.txtProjectList2.BindDictItems(list, "Text", "Value", true, columns.ToArray());

通過上面的兩種方式,我們可以得到常見的兩種下拉選單的資料繫結展示方式。

而對於其他類似的下拉選單,如樹形列表,帶搜尋的SearchLookupEdit等控制元件,我們也可以用類似的方式編寫自定義的擴充套件函數,這樣我們使用起來就非常方便的了。類似我們下面的做法方式,分門別類的對它們進行一些簡單的封裝處理。

以上就是我們對於常見控制元件使用的一些微薄經驗,希望大家有所借鑑。