I use NameValue lists with a top row quite a lot in my current application and find them very useful so your new template is gratefully received.
What would happen with your example code if I required a ProgramNameList on one screen with a top row but on another screen without one (a requirement for me) ? I would call ProgramNameList.GetProgramNameList("0", "None Selected") from the first screen which would load the list. On the second screen I would call ProgramNameList.GetProgramNameList() but as the list was already loaded and _list not null the re-load would not happen would it?
What I have done in this case is make _addTopRow a private static var of the ProgramNameList class and check it along with _list to determine if the list needs to be re-loaded.
Steve
I use NameValue lists with a top row quite a lot in my current application and find them very useful so your new template is gratefully received.
What would happen with your example code if I required a ProgramNameList on one screen with a top row but on another screen without one (a requirement for me) ? I would call ProgramNameList.GetProgramNameList("0", "None Selected") from the first screen which would load the list. On the second screen I would call ProgramNameList.GetProgramNameList() but as the list was already loaded and _list not null the re-load would not happen would it?
What I have done in this case is make _addTopRow a private static var of the ProgramNameList class and check it along with _list to determine if the list needs to be re-loaded.
Steve
I use NameValue lists with a top row quite a lot in my current application and find them very useful so your new template is gratefully received.
What would happen with your example code if I required a ProgramNameList on one screen with a top row but on another screen without one (a requirement for me) ? I would call ProgramNameList.GetProgramNameList("0", "None Selected") from the first screen which would load the list. On the second screen I would call ProgramNameList.GetProgramNameList() but as the list was already loaded and _list not null the re-load would not happen would it?
What I have done in this case is make _addTopRow a private static var of the ProgramNameList class and check it along with _list to determine if the list needs to be re-loaded.
Steve
I can't seem to get it to work. I tried to create a NameValueList from the new template, pointed it at a stored procedure that returns a result set with Id and Name fields and get the following error:
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.Collections.ArrayList.get_Item(Int32 index)
at CodeSmith.Csla.TemplateBase.ObjectInfo.get_Inherits() in c:\dotNet2.0\csla 2.0cs\codesmith 0.9.5\TemplateBase.cs:line 1180
at _CodeSmith.NameValueList_cst.__RenderMethod1(TextWriter writer, Control control) in c:\dotNet2.0\csla 2.0cs\codesmith 0.9.5\NameValueList.cst:line 30
at CodeSmith.Engine.DelegateControl.Render(TextWriter writer)
at CodeSmith.Engine.Control.RenderChildren(TextWriter writer)
at CodeSmith.Engine.CodeTemplate.Render(TextWriter writer)
at CodeSmith.Engine.CodeTemplate.RenderToString()
at CodeSmith.Gui.CodeTemplateGenerator.f(Object A_0, EventArgs A_1)
I couldn't reproduce the error you got but I did find a bug which I fixed. My SP for testing is:
CREATE PROCEDURE [dbo].[GetNameValueTest] AS
SELECT ResultID, ResultName from DmResults
GO
It looks like I can only attach 1 file so I've added a screen shot of the property grid filled out in a way that works with the above SP and the revised template and does not give me an error message.
Generates fine now thanks. Code looks good. I'll let you know when I've had a chance to test it.
Is it worth passing addTopRow into InvalidateCache ? Makes the factory methods a bit tidier:
public static MyObect GetMyObect()
{
if (_addTopRow)
InvalidateCache(false);
if (_list == null)
_list = DataPortal.Fetch<MyObect>(new Criteria());
return _list;
}
public static MyObect GetMyObect(string topRowKey, string topRowValue)
{
if (!_addTopRow)
InvalidateCache(true);
if (_list == null)
_list = DataPortal.Fetch<MyObect>(new Criteria(topRowKey, topRowValue));
return _list;
}
public static void InvalidateCache(bool addTopRow)
{
_list = null;
_addTopRow = addTopRow;
}
Generates fine now thanks. Code looks good. I'll let you know when I've had a chance to test it.
Is it worth passing addTopRow into InvalidateCache ? Makes the factory methods a bit tidier:
public static MyObect GetMyObect()
{
if (_addTopRow)
InvalidateCache(false);
if (_list == null)
_list = DataPortal.Fetch<MyObect>(new Criteria());
return _list;
}public static MyObect GetMyObect(string topRowKey, string topRowValue)
{
if (!_addTopRow)
InvalidateCache(true);
if (_list == null)
_list = DataPortal.Fetch<MyObect>(new Criteria(topRowKey, topRowValue));
return _list;
}public static void InvalidateCache(bool addTopRow)
{
_list = null;
_addTopRow = addTopRow;
}
Yes you can infer the new _addTopRow state from which overload you are in. My code offering was just an attempt at making the state change test a bit tidier. Your way works fine.
Yes you can infer the new _addTopRow state from which overload you are in. My code offering was just an attempt at making the state change test a bit tidier. Your way works fine.
I've attached the modified template which also fixes some bugs in TemplateBase.cs. This is version 0.9.5 of the CSLA 2.0 templates.
I appreciate if you can report back the bugs that you found. It will help me stabilize them quicker.
Thanks,
Ricky
I've attached the modified template which also fixes some bugs in TemplateBase.cs. This is version 0.9.5 of the CSLA 2.0 templates.
I appreciate if you can report back the bugs that you found. It will help me stabilize them quicker.
Thanks,
Ricky
Dan,
Thanks for the bug reports, I'll take a look and have them fixed.
Ricky
Ross,
I like the concept of HeadedBindingList being just a UI thing. Sounds like it's exactly the thing I'm looking for. So yes, I'm very interested in your code...
Cheers,
Herman
Hi,
In case it's applicable. If you using asp.net 2.0, on ListControl base class there is a property AppendDatBoundItems you can consider using:
<asp:DropDownList ID="DropDownList1" AppendDataBoundItems="true" runat="server" DataSourceID="SqlDataSource1" DataTextField="state" DataValueField="state">
<asp:ListItem Text="(Select a State)" Value="" />
</asp:DropDownList>
Thanks,
Ross,
Thanks for posting the HeaderedBindingList code. I played a bit with it and it is exactly what I was looking for!!
Cheers,
Herman
ajj3085:
Ross,
This looks awesome, I'll certainly use it whenever I need this functionality. One question though: Does it play nice with sortedbindinglist? (haven't looked at the code, been busy).
Andy
Gareth,
The code should look something like:
protected void UserListDataSource_SelectObject(object sender, Csla.Web.SelectObjectArgs e)
{
NetShare.Library.UserList obj = GetUserList();
HeaderedBindingList<NetShare.Library.UserList.NameValuePair> hbl =
new HeaderedBindingList<NetShare.Library.UserList.NameValuePair>(obj, NetShare.Library.UserList.NullUser);
e.BusinessObject = hbl;
}
Cheers,
Herman
I'm trying to implement a NVL of active lookup codes.
So when adding a new row the NVL only has Active records in it.
When editing an existing record it is the list of Active records plus the related record if it isinactive.
I'm using HeaderedBindingList to extend the active values for a combo with the current value for the object (which can be an inactive value)
In the code below
* ColorList.GetColorList() gives me all the active colors.
*_originalColorLID and _originalColorName are variables with the original values from the database.
#region ValidColorList
[NonSerialized()]
[NotUndoable()]
private HeaderedBindingList<ColorList.NameValuePair> _validColorList = null;
public HeaderedBindingList<ColorList.NameValuePair> ValidColorList
{
get
{
if (_validColorList == null)
{
if (ColorList.GetColorList().ContainsKey(_originalColorLID))
{
_validColorList = new HeaderedBindingList<ColorList.NameValuePair>(ColorList.GetColorList(), new ColorList.NameValuePair[0]);
}
else
{
_validColorList = new HeaderedBindingList<ColorList.NameValuePair>(ColorList.GetColorList(), new ColorList.NameValuePair(_originalColorLID, _originalColorName));
}
}
return _validColorList ;
}
}
#endregion
Now I want to implement the following property but it gives me an error
public string ColorName
{
get
{
CanReadProperty("ColorName" true);
if (_colorLID == _originalColorLID)
{
return _originalColorName;
}
else
{
return ((ColorList)ValidColorList).GetItemByKey(_colorLID).Value; //=> this gives an error
}
return _colorName;
}
Cannot convert type 'Company.Library.Helper.HeaderedBindingList<Csla.NameValueListBase<int,string>.NameValuePair>' to 'Company.Library.ColorList'
Can you help me with the right syntax? I want to lookup the value in the ValidColorList for a certain key.
I’ve tried also
return ((NameValueListBase<int,string>)ValidKleurList).GetItemByKey(_kleurLID).Value;
but this gives also an error.
If you want to show a blank line at the GUI then it is indeed a responsibility for the GUI.
For that the GUI has two choices:
1) With the DevExpress LookUpEdit control the user can use Ctrl+Del to clear the value.
With the property NullText we can set a text that is displayed when the column contains a null reference.
2) The GUI can add an extra row in the LookUpEdit control because the user doesn’t like Ctrl+Del. This extra row can be either a blank row or a row that shows some text like “[blank]”, etc. Therefore, if a user wants to select nothing, he could just select this extra row.
This feature is the responsibility for the GUI, it has to create a new list, which always return an empty row as the first item.
But in the case I’m describing in my opion it is the responsibilty of the business to deliver the valid list for the GUI (all the active codes + the current code even it is inactive for the concerned record)
This design discussion I find also interesting. But I want to know also the technical answer.
How can I find an item in the list wrapped with the hepler class HeaderedBindingList.
In the NVL list of the CSLA framework there exist a method GetItemByKey.
Could this be possible with the HeaderedBindingList by casting it to a NVL. I don’t think this is possible because it is a wrapper around the NVL and it is not subclassed from NVL.
So how can I have the same possibilities with the HeaderedBindingList as the NVL?
Copyright (c) Marimer LLC