[C#.NET][Infopath 2010] 動態增加 Option button / Dynamic add option button

[C#.NET][Infopath 2010] 動態增加 Option button / Dynamic add option button

Infoapth 2010 許多控制項都有資料binding,偏偏Option button沒有

2010-5-7 下午 11-53-48

像這種單選的控制項有Combo Box或是Drop down list,Option buttin與這兩種控制項不同的是,Option button可以一次把資料秀出來,而另外兩個不行,若你的需求需要把資料一次秀出來,你可以考慮使用下面的解決方案,用程式硬刻!!!

Step1.建立Infopath 資料結構

2010-5-8 上午 12-05-15

Step2.表單UI如下

2010-5-8 上午 12-06-11

 

Step3.分別在Create Row及Delete Row按鈕事件中加入以下程式碼 (*註一)

string MainSection = "/my:myFields/my:group1";
string MainReTable = "/my:myFields/my:group1/my:retable";
string[] TableField = new string[] { "my:id", "my:name" };
bool gDisableEvents = false;
public void CreateTable_Clicked(object sender, ClickedEventArgs e)
{
    gDisableEvents = true;//停用
    XPathNavigator MainData = MainDataSource.CreateNavigator();
    XPathNavigator MainDataSection = MainData.SelectSingleNode(MainSection, NamespaceManager);
    XPathNavigator MainDataReTable = MainDataSection.SelectSingleNode(MainReTable, NamespaceManager); 
 
    //刪除舊的Repeat Table
    XPathNodeIterator AllData = MainDataSection.Select(MainReTable, NamespaceManager);
    if (AllData.Count > 1)//若只有一筆資料不用刪!!!
    {
        XPathNavigator FirstRow = MainDataSection.SelectSingleNode(MainReTable + "[1]", NamespaceManager);
        XPathNavigator EndRow = MainDataSection.SelectSingleNode(MainReTable + "[" + Convert.ToString(AllData.Count - 1) + "]", NamespaceManager);
        FirstRow.DeleteRange(EndRow);
    }
    //增加資料
    for (int i = 0; i < 6; i++)
    {
        //MainDataReTable.SelectSingleNode(TableField[0], NamespaceManager).SetValue(i.ToString());
        MainDataReTable.SelectSingleNode(TableField[1], NamespaceManager).SetValue(i.ToString() + "-value");
        MainDataSection.AppendChild(MainDataReTable);
    }
    //刪除第一行
    XPathNavigator ReadFirst = MainDataSection.SelectSingleNode(MainReTable + "[1]", NamespaceManager);
    ReadFirst.DeleteSelf();
    gDisableEvents = false;//啟用 
 
} 
 
public void DeleteRow_Clicked(object sender, ClickedEventArgs e)
{
    gDisableEvents = true;//停用
    XPathNavigator MainData = MainDataSource.CreateNavigator();
    XPathNavigator MainDataSection = MainData.SelectSingleNode(MainSection, NamespaceManager);
    XPathNavigator MainDataReTable = MainDataSection.SelectSingleNode(MainReTable, NamespaceManager);
    XPathNavigator FirstRow = null;
    XPathNavigator EndRow = null;
    //刪除舊的Repeat Table
    XPathNodeIterator AllData = MainDataSection.Select(MainReTable, NamespaceManager);
    if (AllData.Count > 1)//若只有一筆資料不用刪!!!
    {
        FirstRow = MainDataSection.SelectSingleNode(MainReTable + "[1]", NamespaceManager);
        EndRow = MainDataSection.SelectSingleNode(MainReTable + "[" + Convert.ToString(AllData.Count - 1) + "]", NamespaceManager);
        FirstRow.DeleteRange(EndRow);
    }
    //清除第一列資料
    AllData = MainDataSection.Select(MainReTable, NamespaceManager);
    FirstRow = MainDataSection.SelectSingleNode(MainReTable + "[1]", NamespaceManager);
    foreach (string field in TableField)
    {
        FirstRow.SelectSingleNode(field, NamespaceManager).SetValue("");
    }
    gDisableEvents = false;//啟用
}

Note:因為我不知道該如停用Option Button控制項的事件,所以我用了gDisableEvents變數來決定是否停用,為什麼要有這個東西?

因為當我按下Create Row按鈕後,就會開始畫表格,表格上有Option Button ,而我們有在Option Button事件裡加程式碼,為了不讓在表格還沒建立好就執行程式,故使用此旗標。

 

到目前為止感覺都還不賴只是結果還不是我們要的,沒錯!!!這是多選,在以前還沒有多選時我就是醬子寫的,接下來我們還得針對選取事件做處理。2010-5-8 上午 12-12-42

Step4.在Option button事件中加入以下程式碼

public void id_Changed(object sender, XmlEventArgs e)
{
    if (gDisableEvents == true)//若是停用旗標則離開
    {
        return;
    }
    gDisableEvents = true;
    SingleOption();
    gDisableEvents = false;
}
 
//單選Single Select
private void SingleOption()
{
    string MainSection = "/my:myFields/my:group1";
    string MainReTable = "/my:myFields/my:group1/my:retable";
    string FirstPath = MainSection + "/my:IsSelectFirst";
    string Item = "my:name";
    string Select = "my:id";
    string LastSelectValue = "/my:myFields/my:lastSelect";
    string ItemName = string.Empty;
    string IsSelect = string.Empty;
    string NowValuePath = "/my:myFields/my:select";
    List<string> OptionItem = new List<string>();
    //取得主要資料庫
    XPathNavigator MainData = MainDataSource.CreateNavigator();
    XPathNavigator MainDataSection = MainData.SelectSingleNode(MainSection, NamespaceManager);
    XPathNodeIterator MainDataReTable = MainDataSection.Select(MainReTable, NamespaceManager);
    //判斷是否第一次執行
    XPathNavigator FirstRun = MainData.SelectSingleNode(FirstPath, NamespaceManager);
    bool IstFirst = FirstRun.ValueAsBoolean;
    //記錄上次欄位資料
    XPathNavigator LastValue = MainData.SelectSingleNode(LastSelectValue, NamespaceManager);
    //記錄本次的值
    XPathNavigator NowValue = MainData.SelectSingleNode(NowValuePath, NamespaceManager);
    //找出被勾選的項目
    while (MainDataReTable.MoveNext())
    {
        ItemName = MainDataReTable.Current.SelectSingleNode(Item, NamespaceManager).Value;
        IsSelect = MainDataReTable.Current.SelectSingleNode(Select, NamespaceManager).Value;
        //第一次被勾選的項目
        if (LastValue.Value == "")
        {
            if (IsSelect == "yes")
            {
                FirstRun.SetValue("true");
                LastValue.SetValue(ItemName);
                NowValue.SetValue(ItemName);
                break;
            }
        }
        //第二次以後被勾選的項目
        if ((IstFirst == true) && (LastValue.Value != ""))
        {
            if (IsSelect == "yes")
            {
                OptionItem.Add(ItemName);
            }
        }
    } 
 
    //第二次以後,清除上筆記錄的資料
    if ((IstFirst == true) && (LastValue.Value != ""))
    { 
 
        MainDataReTable = MainDataSection.Select(MainReTable, NamespaceManager);
        while (MainDataReTable.MoveNext())
        {
            ItemName = MainDataReTable.Current.SelectSingleNode(Item, NamespaceManager).Value;
            if (ItemName == LastValue.Value)
            {
                //清除上筆項目
                MainDataReTable.Current.SelectSingleNode(Select, NamespaceManager).SetValue("no");
            }
        }
        //更新上筆資料
        foreach (string data in OptionItem)
        {
            //若資料與上筆相同
            if (LastValue.Value != data)
            {
                //更新上筆選項
                LastValue.SetValue(data);
                NowValue.SetValue(data);
                break;
            }
        }
    }
}

執行結果

2010-5-8 上午 12-56-01

(*註一)建立控制項事件

2010-5-8 上午 12-15-52

2010-5-8 上午 12-20-31

以上,提供一個解決方案參考。

 

 

 

範例下載:Infopath2010DynOption.zip

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo