[C#.NET][Infopath 2010] 動態增加 Option button / Dynamic add option button
Infoapth 2010 許多控制項都有資料binding,偏偏Option button沒有
像這種單選的控制項有Combo Box或是Drop down list,Option buttin與這兩種控制項不同的是,Option button可以一次把資料秀出來,而另外兩個不行,若你的需求需要把資料一次秀出來,你可以考慮使用下面的解決方案,用程式硬刻!!!
Step1.建立Infopath 資料結構
Step2.表單UI如下
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事件裡加程式碼,為了不讓在表格還沒建立好就執行程式,故使用此旗標。
到目前為止感覺都還不賴只是結果還不是我們要的,沒錯!!!這是多選,在以前還沒有多選時我就是醬子寫的,接下來我們還得針對選取事件做處理。
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;
}
}
}
}
執行結果

(*註一)建立控制項事件
以上,提供一個解決方案參考。
範例下載:Infopath2010DynOption.zip
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET