Common Issues and Solutions
1. TextField LabelStyle Property Not Working
This appears to be a bug in ExtJS itself, as Ext.NET generates standard ExtJS configurations based on your settings. Rather than being stuck with this limitation, I implemented the following workaround:
function applyCustomLabelStyle() {
$(".x-form-item-label").addClass("customLabelStyle");
}
By examining the HTML generated by ExtJS, you'll notice that form fields utilize this class. I simply extended it with my custom styles. Remember to execute this function within Ext.onReady.
2. Container Controls Not Triggering Validation
According to documentation, this is an issue with older ExtJS versions. After examining Ext.NET's source code, I discovered it was packaged with ExtJS 3.3.0. Rather than modifying the source, I adopted a different approach. I used FormPanel for all layouts, which worked satisfactorily. For nested layouts, I placed FormPanels inside other FormPanels and set the child FormPanel's Layout to Column. Alternatively, TableLayout provides convenient layout options.
3. Dynamic Addition to CheckboxGroup and RadioGroup
This is another ExtJS limitation. The framework seems to only support SetValues for adding items. In my scenario, I was dynamically adding checkboxes during the Page_Load event. After examining the generated JavaScript, I noticed that Ext.NET creates new Ext.form.Checkbox instances within the checkboxGroup's items property. Even after posting on the Ext.NET forum, I couldn't find a solution. Testing revealed that JavaScript couldn't retrieve values from CheckboxGroup and RadioGroup using '<%=FormPanel1.ClientID%>.getForm().getValues(true)'. This led me to believe it was an ExtJS issue, suggesting that Page_Load should use SetValue for dynamic binding. However, SetValue lacks the three-parameter overload (text, value, selected) I needed. Here's my solution:
Ext.onReady(function() {
initializeGroupValues(<%=dynamicCheckboxGroup.ClientID%>, <%=hiddenValueField.ClientID%>);
initializeGroupValues(<%=dynamicRadioGroup.ClientID%>, <%=hiddenRadioValue.ClientID%>);
});
function initializeGroupValues(groupElement, hiddenField) {
var inputs = $('#' + groupElement.id + ' input[type=checkbox],input[type=radio]');
inputs.change(function() {
var selectedItems = groupElement.getValue();
if (selectedItems !== null && typeof selectedItems.length === 'undefined') {
hiddenField.setValue(selectedItems.tag);
return;
}
var valueString = '';
if (selectedItems !== null) {
for (var i = 0; i < selectedItems.length; i++) {
valueString += selectedItems[i].tag + ";";
}
}
hiddenField.setValue(valueString);
});
}
This approach captures selected values in hidden fields during checkbox and radio button selection events, making them accessible on the server side. A crucial point: when setting values for ExtJS form controls, avoid using properties (text, value) directly, as this only updates the HTML control and won't be submitted. Instead, use the setValue method.
Further testing revealed that FormPanel controls shouldn't use Content elements for layout. Using Items layout resolves these issues. Here's a test case demonstrating this:
<ext:ResourceManager ID="ResourceManager1" runat="server">
</ext:ResourceManager>
<ext:FormPanel ID="MainForm" Collapsible="true" Icon="PageAdd" runat="server"
Title="Dynamic Group Test" MonitorValid="true" Padding="5" ButtonAlign="Right"
Width="830px" Layout="Form">
<Items>
<ext:FormPanel ID="NestedForm" Icon="PhoneAdd" Border="true" Collapsible="true"
runat="server" Title="Dynamic Checkbox Group" AutoHeight="true" LabelWidth="120">
<Items>
<ext:FormPanel runat="server" PaddingSummary="0" Border="false"
ID="CheckboxContainer" Layout="Column">
<Items>
<ext:CheckboxGroup ID="DynamicCheckboxGroup" runat="server">
</ext:CheckboxGroup>
</Items>
</ext:FormPanel>
</Items>
</ext:FormPanel>
<ext:FormPanel ID="AlternativeForm" Icon="PhoneEdit" Border="true" Collapsible="true"
runat="server" Title="Alternative Approach" AutoHeight="true" LabelWidth="120">
<Content>
<ext:FormPanel runat="server" PaddingSummary="0" Border="false"
ID="AlternativeContainer" Layout="Column">
<Items>
<ext:CheckboxGroup ID="AlternativeCheckboxGroup" runat="server">
</ext:CheckboxGroup>
</Items>
</ext:FormPanel>
</Content>
</ext:FormPanel>
</Items>
<Buttons>
<ext:Button ID="SaveButton" runat="server" Icon="Disk" Text="Save">
<DirectEvents>
<Click OnEvent="Save_Click">
</Click>
</DirectEvents>
</ext:Button>
<ext:Button ID="TestButton" runat="server" Icon="Disk" Text="Test">
<DirectEvents>
<Click OnEvent="Test_Click">
</Click>
</DirectEvents>
</ext:Button>
</Buttons>
</ext:FormPanel>
protected void Page_Load(object sender, EventArgs e)
{
DynamicCheckboxGroup.ColumnsNumber = AlternativeCheckboxGroup.ColumnsNumber = 5;
for (int i = 0; i < 10; i++)
{
Ext.Net.Checkbox newCheckbox = new Ext.Net.Checkbox();
newCheckbox.BoxLabel = "Option " + i;
newCheckbox.Tag = i.ToString();
newCheckbox.InputValue = "Value" + i;
DynamicCheckboxGroup.Items.Add(newCheckbox);
Ext.Net.Checkbox alternativeCheckbox = new Ext.Net.Checkbox();
alternativeCheckbox.BoxLabel = "Alt Option " + i;
alternativeCheckbox.Tag = i.ToString();
alternativeCheckbox.InputValue = "AltValue" + i;
AlternativeCheckboxGroup.Items.Add(alternativeCheckbox);
}
}
protected void Save_Click(object sender, DirectEventArgs e)
{
string result = string.Empty;
foreach (var item in DynamicCheckboxGroup.Items)
{
result += item.BoxLabel + ": " + item.InputValue + ": " + item.Checked + "\n";
}
ResourceManager1.AddScript("alert('" + result + "');");
}
protected void Test_Click(object sender, DirectEventArgs e)
{
string result = string.Empty;
foreach (var item in AlternativeCheckboxGroup.Items)
{
result += item.BoxLabel + ": " + item.InputValue + ": " + item.Checked + "\n";
}
ResourceManager1.AddScript("alert('" + result + "');");
}
Overall, ExtJS is a solid framework, and Ext.NET makes it more accessible for .NET developers. The following resources proved invaluable during my learning process: