UOF2 客製欄位可搜尋的下拉選單 從資料庫來源資料 | EIP | BPM | WebForm

by | 4 月 15, 2026 | 一等一UOF系統, 程式 | 0 comments

Views: 3

這篇原本是上一篇的延續,不過我想還是開一篇新的好了

準備工作

  • UOF2 開發環境,這篇教學使用的是28.5
  • 外掛欄位產生器
  • Visual Studio ,這篇開始我使用的開發版本是 2026
  • 資料

準備資料庫的資料

這邊簡單自己搭一下,假設我們要做個出貨單,要有客戶資料,大概有這幾個欄位

資料表為Z_WISH_BP_INFO

Image

資料部分就簡單餵準備個十幾筆就好

懶得操作的小夥伴這邊也有準備好的Script

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Z_WISH_BP_INFO](
	[UID] [nvarchar](20) NOT NULL,
	[ADDRESS] [nvarchar](200) NULL,
	[TITLE] [nvarchar](50) NULL,
	[PHONE] [nvarchar](50) NULL,
	[CONTACT] [nvarchar](50) NULL,
 CONSTRAINT [PK_Z_WISH_BP_INFO] PRIMARY KEY CLUSTERED 
(
	[UID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'00000000', N'', N'顧客', N'08-', N'門市購買')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'01234567', N'台北市中山區', N'量販店A', N'03-', N'陳經理')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'02233445', N'台北市士林區', N'超市A', N'05', N'林先生')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'03112233', N'高雄市前鎮區', N'麻辣燙A', N'022-', N'黃經理')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'03124231', N'澎湖縣馬公鄕', N'手機行B', N'03-', N'薛經理')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'03333224', N'台中市北屯區', N'書局A', N'06-', N'孫小美')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'04211253', N'桃園市觀音區', N'手機行A', N'04-', N'阿土伯')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'32401234', N'桃園市中壢區', N'書局B', N'089-', N'錢夫人')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'54254351', N'新北板橋市', N'手機行D', N'04-', N'蔡小組')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'54354552', N'花蓮縣光復鄉', N'燈具行', N'05-', N'張簡先生')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'58082341', N'屏東縣恆春鎮', N'手機行C', N'03-', N'金貝貝')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'82314234', N'新北市三峽區', N'超市B', N'05-', N'阿土伯')
GO
INSERT [dbo].[Z_WISH_BP_INFO] ([UID], [ADDRESS], [TITLE], [PHONE], [CONTACT]) VALUES (N'87994435', N'台北信義區', N'麻辣燙B', N'05-', N'金貝貝')
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'統編' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Z_WISH_BP_INFO', @level2type=N'COLUMN',@level2name=N'UID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'地址' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Z_WISH_BP_INFO', @level2type=N'COLUMN',@level2name=N'ADDRESS'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'抬頭' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Z_WISH_BP_INFO', @level2type=N'COLUMN',@level2name=N'TITLE'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'連絡電話' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Z_WISH_BP_INFO', @level2type=N'COLUMN',@level2name=N'PHONE'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'聯絡人' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Z_WISH_BP_INFO', @level2type=N'COLUMN',@level2name=N'CONTACT'
GO

產生外掛欄位

這邊依照需求填寫

Image

這邊設定好直接匯出就好了

Image

動作>匯出成外掛欄位,依照版本選擇

Image

  • plugIn.xml,選網站目錄App_Data下的plugIn.xml
  • 匯出外掛欄位,選網站目錄CDS底下的資料夾

Image

表單設計

這邊簡單我們設計另外一個DEMO下拉選單資料庫版,做客製欄位有兩個重點,先設計簡單的流程自己簽就好,然後發佈表單。

表單名稱我訂為 DEMO下拉選單(資料庫來源)

Image

Image

同樣設計好直接發佈,等下再來是寫程式時間

程式碼 DropDownDemoDbUC.ascx

DropDownDemoDbUC.ascx

這邊先加入表單需要的欄位

下拉選單我推薦使用RadComboBox 這邊直接照抄就好

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="DropDownDemoDbUC.ascx.cs" Inherits="WKF_OptionalFields_DropDownDemoDbUC" %>
<%@ Reference Control="~/WKF/FormManagement/VersionFieldUserControl/VersionFieldUC.ascx" %>

<table class="PopTable">
    <tr>
        <td>公司</td>
        <td>
            <label ID="lblDEMO_SHOW" runat="server" Text="" ></label>
            <telerik:RadComboBox runat="server" ID="rcbDEMO"
                                 Filter="Contains"
                                 DropDownAutoWidth="Disabled"
                                 AutoPostBack="true"
                                 CausesValidation="False"/>
            <asp:HiddenField runat="server" ID="hidDEMO" />
            <asp:HiddenField runat="server" ID="hidDEMO_NAME" />
        </td>
    </tr>
    <tr>
        <td>統編</td>
        <td><label ID="lblDEMO_UID" runat="server" Text="" ></label></td>
    </tr>
    <tr>
        <td>地址</td>
        <td><label ID="lblDEMO_ADDR" runat="server" Text="" ></label></td>
    </tr>
    <tr>
        <td>電話</td>
        <td><label ID="lblDEMO_PHONE" runat="server" Text="" ></label></td>
    </tr>
    <tr>
        <td>聯絡人</td>
        <td><label ID="lblDEMO_CONTACT" runat="server" Text="" ></label></td>
    </tr>
</table>

<asp:Label ID="lblHasNoAuthority" runat="server" Text="無填寫權限" ForeColor="Red" Visible="False" meta:resourcekey="lblHasNoAuthorityResource1"></asp:Label>
<asp:Label ID="lblToolTipMsg" runat="server" Text="不允許修改(唯讀)" Visible="False" meta:resourcekey="lblToolTipMsgResource1"></asp:Label>
<asp:Label ID="lblModifier" runat="server" Visible="False" meta:resourcekey="lblModifierResource1"></asp:Label>
<asp:Label ID="lblMsgSigner" runat="server" Text="填寫者" Visible="False" meta:resourcekey="lblMsgSignerResource1"></asp:Label>
<asp:Label ID="lblAuthorityMsg" runat="server" Text="具填寫權限人員" Visible="False" meta:resourcekey="lblAuthorityMsgResource1"></asp:Label>

Image

然後看一下申請畫面,我說一下程式碼的關鍵點

  • telerik:RadComboBox 這個是telerik這間公司出品的.Net元件,這邊下拉選單直接使用這個,UOF2本身有包含它的授權(應該),使用它的原因是它本身自帶搜尋功能。telerik的說明

telerik:RadComboBox 的屬性說明

  • Filter="Contains" 啟用搜尋功能 可以模糊搜尋
  • DropDownAutoWidth="Disabled" 關閉自動調整寬度
  • AutoPostBack="true" 自動回傳選擇值給後端
  • CausesValidation="False" 不要觸發表單驗證

這邊我還沒寫改變要Post什麼到後端

後端加上資料來源 DropDownDemoDbUC.ascx.cs

DropDownDemoDbUC.ascx.cs
/// <summary>
/// 設定元件狀態
/// </summary>
/// <param name="Enabled">是否啟用輸入元件</param>
public void EnabledControl(bool Enabled)
{
    if (Enabled)
    {
        //啟用輸入元件的處理
        if (!IsPostBack)
        {
            BindRcbDEMO();
        }
    }
    else
    {
        //停用輸入元件的處理+顯示資料
        lblDEMO_SHOW.Text = hidDEMO_NAME.Value;
        rcbDEMO.Visible = false;
    }
}

/// <summary>
/// 抓EIP Web.Config的連線字串
/// 如果連接其他資料庫請自行修改連線字串名稱
/// </summary>
private readonly string _connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["connectionstring"].ConnectionString;

/// <summary>
/// 綁定下拉選單內容 從資料庫抓資料
/// </summary>
public void BindRcbDEMO()
{
    string sql = @"
        SELECT  [UID] --統編
              --,[ADDRESS] -- 地址
              ,[TITLE] -- 公司名稱
              --,[PHONE] -- 電話
             -- ,[CONTACT] -- 聯絡人
          FROM [Z_WISH_BP_INFO]
        ";
    var data = new DataTable();
    using (var conn = new SqlConnection(_connectionString))
    using (var cmd = new SqlCommand(sql, conn))
    using (var adapter = new SqlDataAdapter(cmd))
    {
        adapter.Fill(data);
    }
    rcbDEMO.DataTextField = "TITLE";
    rcbDEMO.DataValueField = "UID";
    //加入請選擇
    rcbDEMO.Items.Insert(0, new RadComboBoxItem("-- 請選擇 --", ""));
    rcbDEMO.DataSource = data;
    rcbDEMO.DataBind();
}
  • EnabledControl() 這邊是外掛欄位產生器自帶的函數,這邊加上可以修改時載入下拉選單資料
  • _connectionString 讀取資料庫連線字串的標準寫法,我習慣放在類別的最頂端
  • BindRcbDEMO() 從資料庫讀取下拉選單的內容,這邊我用純ADO.NET的寫法,傳統上這類要綁定資料都會用Bind來命名函數

Image

測試搜尋

Image

選擇後載入資料

Image

OnSelectedIndexChanged="rcbDEMO_OnSelectedIndexChanged"

這邊前端加入事件 OnSelectedIndexChanged="rcbDEMO_OnSelectedIndexChanged"


後端加入選擇後事件 OnSelectedIndexChanged

DropDownDemoDbUC.ascx.cs

/// <summary>
/// 選擇下拉選單後事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void rcbDEMO_OnSelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
{
    GetData(rcbDEMO.SelectedValue);
}

/// <summary>
/// 下拉選單變更後,取得資料庫資料顯示在欄位上
/// </summary>
/// <param name="uid"></param>
public void GetData(string uid)
{
    //請自行撰寫SQL語法,取得下拉選單選取後
    string sql = @"
        SELECT  TOP 1 
               [UID] --統編
              ,[ADDRESS] -- 地址
              ,[TITLE] -- 公司名稱
              ,[PHONE] -- 電話
              ,[CONTACT] -- 聯絡人
          FROM [Z_WISH_BP_INFO]
        WHERE UID = @UID
        ";
    var data = new DataTable();

    using (var conn = new SqlConnection(_connectionString))
    using (var cmd = new SqlCommand(sql, conn))
    using (var adapter = new SqlDataAdapter(cmd))
    {
        cmd.Parameters.Add("@UID", SqlDbType.NVarChar).Value = uid;
        adapter.Fill(data);
    }

    //將資料從data table顯示在欄位上
    lblDEMO_UID.Text = String.Empty;
    lblDEMO_ADDR.Text = String.Empty;
    lblDEMO_PHONE.Text = String.Empty;
    lblDEMO_CONTACT.Text = String.Empty;
    if (data.Rows.Count > 0)
    {
        DataRow row = data.Rows[0];
        lblDEMO_UID.Text = Convert.ToString(row["UID"]);
        lblDEMO_ADDR.Text = Convert.ToString(row["ADDRESS"]);
        lblDEMO_PHONE.Text = Convert.ToString(row["PHONE"]);
        lblDEMO_CONTACT.Text = Convert.ToString(row["CONTACT"]);
    }
}

測試

Image

選擇後就會自動帶入資料,這樣寫大概就OK了

處理表單儲存 FieldValue()

DropDownDemoDbUC.ascx.cs

/// <summary>
/// 欄位的內容
/// </summary>
public override string FieldValue
{
    get
    {
        //回傳字串
        //取得表單欄位填寫的內容
        XmlDocument xmlDoc = new XmlDocument();
        var docEle = xmlDoc.CreateElement("FieldValue");
        xmlDoc.AppendChild(docEle);
        docEle.SetAttribute("hidDEMO", hidDEMO.Value);
        docEle.SetAttribute("hidDEMO_NAME", hidDEMO_NAME.Value);
        docEle.SetAttribute("DEMO_UID", lblDEMO_UID.Text);
        docEle.SetAttribute("DEMO_ADDR", lblDEMO_ADDR.Text);
        docEle.SetAttribute("DEMO_PHONE", lblDEMO_PHONE.Text);
        docEle.SetAttribute("DEMO_CONTACT", lblDEMO_CONTACT.Text);
        return xmlDoc.InnerXml;
    }
    set
    {
	//這個屬性不用修改
        base.m_fieldValue = value;
    }
}

處理表單載入 SetField()

DropDownDemoDbUC.ascx.cs

/// <summary>
/// 顯示時欄位初始值
/// </summary>
/// <param name="versionField">欄位集合</param>
public override void SetField(Ede.Uof.WKF.Design.VersionField versionField)
{
    FieldOptional fieldOptional = versionField as FieldOptional;

    if (fieldOptional != null)
    {

        //若有擴充屬性,可以用該屬性存取
        // fieldOptional.ExtensionSetting

        XmlDocument xmlDoc = new XmlDocument();

        if (!string.IsNullOrWhiteSpace(fieldOptional.FieldValue))
        {
            xmlDoc.LoadXml(fieldOptional.FieldValue);
            XmlNode node = xmlDoc.SelectSingleNode("FieldValue");
            if (node != null && (!IsPostBack))
            {
                hidDEMO_NAME.Value = node.Attributes["hidDEMO_NAME"]?.Value;
                hidDEMO.Value = node.Attributes["hidDEMO"]?.Value;
                lblDEMO_UID.Text = node.Attributes["DEMO_UID"]?.Value;
                lblDEMO_ADDR.Text = node.Attributes["DEMO_ADDR"]?.Value;
                lblDEMO_PHONE.Text = node.Attributes["DEMO_PHONE"]?.Value;
                lblDEMO_CONTACT.Text = node.Attributes["DEMO_CONTACT"]?.Value;

            }
        }
        //..其他的程式碼
    }
}

簽核時不能更新欄位

DropDownDemoDbUC.ascx.cs

/// <summary>
/// 顯示時欄位初始值
/// </summary>
/// <param name="versionField">欄位集合</param>
public override void SetField(Ede.Uof.WKF.Design.VersionField versionField)
{
    //其他程式碼
    switch(fieldOptional.FieldMode)
    {
        case FieldMode.Signin: //加入簽核時不能變更選項
        case FieldMode.Print:
        case FieldMode.View:
            //觀看和列印都需作沒有權限的處理
            EnabledControl(false);
            break;
    }
    //其他程式碼
}

處理簽核顯示

這邊之前的程式碼我有改過了,這裡僅是說明怎麼實作

DropDownDemoDbUC.ascx.cs

/// <summary>
/// 設定元件狀態
/// </summary>
/// <param name="Enabled">是否啟用輸入元件</param>
public void EnabledControl(bool Enabled)
{
    if (Enabled)
    {
        //啟用輸入元件的處理
        if (!IsPostBack)
        {
            BindRcbDEMO();
        }
    }
    else
    {
        //停用輸入元件的處理+顯示資料
        lblDEMO_SHOW.Text = hidDEMO_NAME.Value;
        rcbDEMO.Visible = false;
    }
}

這邊主要是這兩行處理簽核顯示
lblDEMO_SHOW.Text = hidDEMO_NAME.Value;
rcbDEMO.Visible = false;

加入必填驗證

<telerik:RadComboBox runat="server" ID="rcbDEMO"
                     Filter="Contains"
                     DropDownAutoWidth="Disabled"
                     AutoPostBack="true"
                     CausesValidation="False"
                     OnSelectedIndexChanged="rcbDEMO_OnSelectedIndexChanged"
                     />
<!-- 加入驗證 -->
<asp:RequiredFieldValidator ID="rfvDEMO" runat="server" ControlToValidate="rcbDEMO" InitialValue="-- 請選擇 --" ErrorMessage="請選擇一個選項" ForeColor="Red"></asp:RequiredFieldValidator>

Image

測試儲存與草稿載入

(略)

測試檢視表單

Image

測試簽核

Image

完整程式碼

gist網址

0 Comments

Submit a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *