I'm using Devexpress
I have a TextEdit when i want that users to have 2 dates as following :
dd/MM/yyyy - dd/MM/yyyy ( for example : 02/12/2011-03/09/2013 )
I've tried to set the mask as above but is not working.
It is possible to set mask:
textEdit.Properties.Mask.MaskType = MaskType.Simple;
textEdit.Properties.Mask.EditMask = "00/00/0000-00/00/0000";
However, TextEdit can have only one EditValue property, so it won't allow you to store two DateTime values.
You can add custom validating with Validating event:
private void TextEdit_Validating(object sender, CancelEventArgs e)
{
string textValue = (string)(sender as TextEdit).EditValue;
var dates = textValue?.Split('-').Select(x => { DateTime.TryParse(x, out DateTime result); return result; });
if (dates == null || dates.Any(x => x == null))
{
e.Cancel = true;
}
}
But it seems messy, so i recommend you to use two DateEdit controls instead.
Related
Scenario:
User submits search criteria and selects an item from search results on the same page, which navigates to a new page of details for the selected item.
When the User returns to the search screen, the search criteria & results (including selected page and sort-order) should be preserved from their last visit.
Related information:
All form submissions are POSTs.
Navigation back to the search screen may not be available from last browser history (e.g. more than one details screen may be encountered, or the user may navigate directly to the search screen from an alternative menu.)
Search results are provided using Telerik RadGrid control.
I'm looking for a generic solution that will be able to be applied to different search screens.
In some instances, the item may be DELETED from within the details screen, and should therefore not appear in the search results when the screen is next encountered.
Thoughts:
I've read a lot of suggested methods for addressing various parts of this scenario, but I'm still confused; no comprehensively "correct" solution jumps to the forefront.
I guess I'm asking for recommendations/approach rather than a whole solution spelled out for me (although that would be nice! ;-)
The .NET VIEWSTATE would seem to do exactly what I'm after (with the exception of #5) - Is there some way of leveraging off this so that viewstate can be used between pages, and not just between postbacks to the same page? (e.g. can I store/restore viewstate to/from a session variable or something? I haven't seen this suggested anywhere and I'm wondering if there's a reason why.)
Thanks in advance.
Thanks for all the advice.
For the benefit of others, here is a solution to this issue (no doubt there's room for improvement, but this works satisfactorily for the moment).
4 functions...
StoreSearchCookie - Persist the state/values of a panel of search criteria and a results grid in a cookie with a specified UID.
RestoreSearchCookie_Criteria - Read the cookie and re-populate the search criteira
RestoreSearchCookie_Results - Read the cookie and restore the grid state.
FindFormControls - Helper method to recursively find form-input controls in a container (pinched & modified from elsewhere on Stack Overflow)
NB...
I haven't addressed the multiple-tabs issue because our application doesn't allow them anyway.
RestoreSearchResults utilises GridSettingsPersister.cs available from Telerik website, (but I had to modify it to store the page number as well)
Usage is as follows...
protected void Page_PreRender(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
// Store the state of the page
StoreSearchCookie("SomeSearchPage", pnlSearchCriteria, gridResults);
}
else
{
// Restore search criteria
RestoreSearchCookie_Criteria("SomeSearchPage");
// Re-invoke the search here
DoSearch(); // (for example)
// Restore the grid state
RestoreSearchCookie_Results("SomeSearchPage");
}
}
Code follows...
protected void StoreSearchCookie(string cookieName, Panel SearchPanel, RadGrid ResultsGrid)
{
try
{
HttpCookie cookieCriteria = new HttpCookie("StoredSearchCriteria_" + cookieName);
// 1. Store the search criteria
//
List<Control> controls = new List<Control>();
FindFormControls(controls, SearchPanel);
foreach (Control control in controls)
{
string id = control.ID;
string parentId = control.Parent.ID;
string uid = string.Format("{0}>{1}", parentId, id);
string value = "";
Type type = control.GetType();
bool isValidType = true; // Optimistic!
if (type == typeof(TextBox))
{
value = ((TextBox)control).Text;
}
else if (type == typeof(DropDownList))
{
value = ((DropDownList)control).SelectedValue;
}
else if (type == typeof(HiddenField))
{
value = ((HiddenField)control).Value;
}
else if (type == typeof(RadioButton))
{
value = ((RadioButton)control).Checked.ToString();
}
else if (type == typeof(CheckBox))
{
value = ((CheckBox)control).Checked.ToString();
}
else
{
isValidType = false;
}
if (isValidType)
{
cookieCriteria.Values[uid] = value;
}
}
cookieCriteria.Expires = DateTime.Now.AddDays(1d);
Response.Cookies.Add(cookieCriteria);
// 2. Persist the grid settings
//
GridSettingsPersister SavePersister = new GridSettingsPersister(ResultsGrid);
HttpCookie cookieResults = new HttpCookie("StoredSearchResults_" + cookieName);
cookieResults.Values["GridId"] = ResultsGrid.ID;
cookieResults.Values["GridSettings"] = SavePersister.SaveSettings();
cookieResults.Expires = DateTime.Now.AddDays(1d);
Response.Cookies.Add(cookieResults);
}
catch (Exception exception)
{
Logger.Write(exception);
}
}
protected void RestoreSearchCookie_Criteria(string cookieName)
{
try
{
HttpCookie cookieCriteria = Request.Cookies["StoredSearchCriteria_" + cookieName];
if (cookieCriteria != null)
{
foreach (string key in cookieCriteria.Values.AllKeys)
{
string value = cookieCriteria[key];
string[] ids = key.Split('>');
string parentId = ids[0];
string id = ids[1];
Control control = FindControl(parentId).FindControl(id);
Type type = control.GetType();
if (type == typeof(TextBox))
{
((TextBox)control).Text = value;
}
else if (type == typeof(DropDownList))
{
((DropDownList)control).SelectByValue(value);
}
else if (type == typeof(HiddenField))
{
((HiddenField)control).Value = value;
}
else if (type == typeof(RadioButton))
{
((RadioButton)control).Checked = Boolean.Parse(value);
}
else if (type == typeof(CheckBox))
{
((CheckBox)control).Checked = Boolean.Parse(value);
}
}
}
}
catch (Exception exception)
{
Logger.Write(exception);
}
}
protected void RestoreSearchCookie_Results(string cookieName)
{
try
{
HttpCookie cookieResults = Request.Cookies["StoredSearchResults_" + cookieName];
if (cookieResults != null)
{
string gridId = cookieResults.Values["GridId"];
string settings = cookieResults.Values["GridSettings"];
RadGrid grid = (RadGrid)FindControl(gridId);
GridSettingsPersister LoadPersister = new GridSettingsPersister(grid);
LoadPersister.LoadSettings(settings);
grid.Rebind();
}
}
catch (Exception exception)
{
Logger.Write(exception);
}
}
private void FindFormControls(List<Control> foundSofar, Control parent)
{
List<Type> types = new List<Type> { typeof(TextBox), typeof(DropDownList), typeof(RadioButton), typeof(CheckBox), typeof(HiddenField) };
foreach (Control control in parent.Controls)
{
if (types.Any(item => item == control.GetType()))
{
foundSofar.Add(control);
}
if (control.Controls.Count > 0)
{
this.FindFormControls(foundSofar, control); // Use recursion to find all descendants.
}
}
}
I tried to Filter an ASPxComboBox that gets data using an XpoDataSource, note that restoring and filtering data from a small data set works fine , the issue start when I try to filter large dataset - about 70000 records- from datasource the ComboBox loading becomes very slow since XpoDataSource gets all data from database table .
So I created a criteria for the XpoDataSource to reduce number of records restored ,then the ComboBox Keeps repeating the top 10 records while scrolling down the ComboBox, I don't know where the problem is.
I realized that what I need is similar to the example in the following link
But using an XpoDataSource instead of SqlDataSource1 .
I don't know how to write a similar code for an XpoDataSource .
this is my code :
protected void cmbServices_OnItemRequestedByValue_SQL(object source, DevExpress.Web.ASPxEditors.ListEditItemRequestedByValueEventArgs e)
{
try
{
string criteria = "";
if (string.IsNullOrEmpty(e.Value.ToString()) || e.Value.ToString().Length < 3)
{
criteria = "1 = 2";
}
else
{
criteria =
string.Format("(( Code like '{0}%' OR ProductName like '{0}%') AND CustomerId = {1})", e.Value.ToString(), (cmbServicesActivities != null && cmbServicesActivities.Value != null) ? cmbServicesActivities.Value.ToString() : "0");
}
dsServices.Session = LookupsSession;
dsServices.Criteria = criteria;
cmbServicesDescription.DataSource = dsServices;
cmbServicesDescription.DataBind();
}
catch (Exception exc)
{
Debug.WriteLine(exc.Message);
}
}
The Following Example demonstrates the answer of my question
public partial class _Default : System.Web.UI.Page {
Session session = XpoHelper.GetNewSession();
protected void cmb_ItemRequestedByValue(object source, DevExpress.Web.ASPxEditors.ListEditItemRequestedByValueEventArgs e) {
MyObject obj = session.GetObjectByKey<MyObject>(e.Value);
if (obj != null) {
cmb.DataSource = new MyObject[] { obj };
cmb.DataBindItems();
}
}
protected void cmb_ItemsRequestedByFilterCondition(object source, DevExpress.Web.ASPxEditors.ListEditItemsRequestedByFilterConditionEventArgs e) {
XPCollection<MyObject> collection = new XPCollection<MyObject>(session);
collection.SkipReturnedObjects = e.BeginIndex;
collection.TopReturnedObjects = e.EndIndex - e.BeginIndex + 1;
collection.Criteria = new BinaryOperator("Title", String.Format("%{0}%", e.Filter), BinaryOperatorType.Like);
collection.Sorting.Add(new SortProperty("Oid", DevExpress.Xpo.DB.SortingDirection.Ascending));
cmb.DataSource = collection;
cmb.DataBindItems();
}
I'm experiencing some problems and right now I don't know how to solve it. The web control simply updates a clock represented by a label every second. My issue is that the web control exposes a property called 'Formato' where the user can select to display in format 12 or 24 hours. This is done with an enum type where in spanish Doce means 12 and Veinticuatro means 24. This is the code for the server control:
namespace Ejercicio2RelojControl
{
public enum _FormatoHora
{
Doce,
Veinticuatro
}
[DefaultProperty("FormatoHora")]
[ToolboxData("<{0}:Ejercicio2RelojControl runat=server></{0}:Ejercicio2RelojControl>")]
[ToolboxBitmap(typeof(Ejercicio2RelojControl), "Ejercicio2RelojControl.Ejercicio2RelojControl.ico")]
//[Designer("Ejercicio2RelojControl.Ejercicio2RelojControlDesigner, Ejercicio2RelojControl")]
public class Ejercicio2RelojControl : WebControl
{
public Ejercicio2RelojControl()
{
}
[
//Bindable(true),
Category("Appearance"),
//DefaultValue(_FormatoHora.Doce),
Description(""),
]
public virtual _FormatoHora FormatoHora
{
get
{
//object t = ViewState["FormatoHora"];
//return (t == null) ? _FormatoHora.Doce : (_FormatoHora)t;
object obj2 = this.ViewState["_FormatoHora"];
if (obj2 != null)
{
return (_FormatoHora)obj2;
}
return _FormatoHora.Doce;
}
set
{
ViewState["_FormatoHora"] = value;
}
}
//Create one TimerControl
Timer timer = new Timer();
private Label clockLabel = new Label();
// Declare one Updatepanel
UpdatePanel updatePanel = new UpdatePanel();
// Now override the Load event of Current Web Control
protected override void OnLoad(EventArgs e)
{
//Text = "hh:mm:ss";
// Create Ids for Control
timer.ID = ID + "_tiker";
clockLabel.ID = ID + "_l";
// get the contentTemplate Control Instance
Control controlContainer = updatePanel.ContentTemplateContainer;
// add Label and timer control in Update Panel
controlContainer.Controls.Add(clockLabel);
controlContainer.Controls.Add(timer);
// Add control Trigger in update panel on Tick Event
updatePanel.Triggers.Add(new AsyncPostBackTrigger() { ControlID = timer.ID, EventName = "Tick" });
updatePanel.ChildrenAsTriggers = true;
// Set default clock time in label
clockLabel.Text = DateTime.Now.ToString("h:mm:ss tt");
//clockLabel.Text = DateTime.Now.ToString("H:mm:ss");
// Set Interval
timer.Interval = 1000;
// Add handler to timer
timer.Tick += new EventHandler<EventArgs>(timer_Tick);
updatePanel.RenderMode = UpdatePanelRenderMode.Block;
//Add update panel to the base control collection.
base.Controls.Add(updatePanel);
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write(FormatoHora);
}
void timer_Tick(object sender, EventArgs e)
{
// Set current date time in label to move current at each Tick Event
clockLabel.Text = DateTime.Now.ToString("h:mm:ss tt");
//clockLabel.Text = DateTime.Now.ToString("H:mm:ss");
}
}
}
Now it's time to test the custom control in an asp.net web application.
<cc1:Ejercicio2RelojControl ID="Ejercicio2RelojControl1" runat="server" />
Works great! BUT when I add the property "Formato" fails at compile time:
<cc1:Ejercicio2RelojControl ID="Ejercicio2RelojControl1" runat="server" Formato="Doce" />
Compiler Error Message: CS0117: 'Ejercicio2RelojControl.Ejercicio2RelojControl' does not contain a definition for 'FormatoHora'
Why is the property Formato making the web app crash at compile time?
Thanks a lot.
EDIT:
namespace Ejercicio2RelojControl
{
public enum FormatoHora
{
Doce,
Veinticuatro
}
[DefaultProperty("FormatoHora")]
[ToolboxData("<{0}:Ejercicio2RelojControl runat=server></{0}:Ejercicio2RelojControl>")]
public class Ejercicio2RelojControl : WebControl, INamingContainer
{
public FormatoHora FormatoHora
{
get
{
object obj2 = this.ViewState["FormatoHora"];
if (obj2 != null)
{
return (FormatoHora)obj2;
}
return FormatoHora.Doce;
}
set
{
ViewState["FormatoHora"] = value;
}
}
As you can see I've changed the public property. Now the error has changed. Is the following:
Compiler Error Message: CS0120: An object reference is required for the non-static field, method, or property 'Ejercicio2RelojControl.Ejercicio2RelojControl.FormatoHora.get'
Any help appreciated. Thanks
EDIT 2:
I've discovered that the problem is on the set {}. If I comment it, all is working fine but then I cannot change FormatoHora between 12 and 24 because of is read only due to only get{} is implemented. Any help with the implementation of set{} ?
I am here for giving you the solution:
You are using the same name for the namespace and for the webcontrol (Ejercicio2RelojControl) . Simply change that and your code will work fine.
Hope it helps, despite the fact some years have passed :)
I am developing a custom control that needs to display a dropdownlist as a composite control.
The drop down list gets populated from a Rest web service. The problem I am facing is that the dropdownlist only has DataTextField and DataValueField but I need a way of storing more values in the control i.e. I have a couple of other properties I need to access for the selected item.
What is the best way of going about this?
Here is the code I have so far:
[ValidationProperty("SelectedValue")]
public class SelectSurveyControl : Panel
{
private DropDownList ddlSurveys;
public string SelectedSurveyId
{
get
{
return SelectedValue;
}
}
public string SelectedSurveyJavascriptEmbedCode
{
get
{
return this.ddlSurveys.SelectedItem.Attributes[""];
}
}
public string SelectedValue
{
get
{
return ddlSurveys.SelectedValue;
}
set
{
if (ddlSurveys == null)
{
ddlSurveys = new DropDownList();
}
ddlSurveys.SelectedValue = value;
}
}
protected override void OnLoad(EventArgs e)
{
base.OnInit(e);
if (ddlSurveys == null)
{
ddlSurveys = new DropDownList();
}
IList<Survey> surveys = GetSurveys();
this.ddlSurveys.DataSource = surveys;
this.ddlSurveys.DataTextField = "title";
this.ddlSurveys.DataValueField = "id";
this.ddlSurveys.DataBind();
ddlSurveys.SelectedValue = this.SelectedValue;
ddlSurveys.CssClass = "umbEditorTextFieldMultiple charlimit";
ddlSurveys.Attributes.Add("SurveyId", SelectedSurveyId);
ddlSurveys.Attributes.Add("JavascriptEmbedingCode", SelectedSurveyId);
this.Controls.Add(ddlSurveys);
}
public IList<Survey> GetSurveys()
{
...
}
}
Try using a string join/split to store and retrieve the various values, then you don't have to customize your dropdown list very much.
For Example:
Text: Some Title
Value: 1|testing test|2/12/2010
This will let you store as many values as you want, so long as you choose an appropriate character to join and split on. I usually use the bar, as in my example above.
Side Note: I was looking at your selected value set handler and it needs some tweaking. You shouldn't check for a null drop down list, instead you should call EnsureChildControls() before each get and set instead. Make sure you override the CreateChildControls() method and create your controls there.
You could use a hidden field and iterate thru a copy of the returned Surveys like this:
foreach(Survey s in Surveys){
string val = s.id + ":" + s.<property1> + ":" + s.<property2>;
hiddenField.Value += val +",";
}
When you need to read from the hidden field, you use String.Split to separate the values into arrays using ',' as the separator and in each array, you split again using ':'.
In the first split Array1[0] who be the survey id and Array1[n!=0] would be the properties of the Survey with the id = Array1[0]. Array[n!=0] would then be split into Array2.
I would suggest handling empty property values with an empty string or something or else you might end up with unequal lengths especially if you specify StringSplitOptions.RemoveEmptyEntries.
Agricfowl
In Flex I'm using the following code to allow sorting in a DataGrid (the data is paged and sorted serverside).
private function headerReleaseHandler(event:DataGridEvent):void
{
var column:DataGridColumn = DataGridColumn(event.currentTarget.columns[event.columnIndex]);
if(this.count>0)
{
if(this.query.SortField == column.dataField)
{
this.query.SortAscending = !this.query.SortAscending;
}
else
{
this.query.SortField = column.dataField;
this.query.SortAscending = true;
}
this.fill();
}
event.preventDefault();
}
This works perfectly, except that the arrows that indicate sorting isn't shown. How can I accomplish that?
Thanks!
/Niels
There is an example here if this is what you are looking for:
http://blog.flexexamples.com/2008/02/28/displaying-the-sort-arrow-in-a-flex-datagrid-control-without-having-to-click-a-column/
It looks like you need to refresh the collection used by your dataprovider.
I have encountered the same problem and the only solution I found was to override the DataGrid and create a custom one.
Here is the class:
public class DataGridCustomSort extends DataGrid
{
public function DataGridCustomSort()
{
super();
addEventListener(DataGridEvent.HEADER_RELEASE,
headerReleaseHandlerCustomSort,
false, EventPriority.DEFAULT_HANDLER);
}
public function headerReleaseHandlerCustomSort(event:DataGridEvent):void {
mx_internal::sortIndex = event.columnIndex;
if (mx_internal::sortDirection == null || mx_internal::sortDirection == "DESC")
mx_internal::sortDirection = "ASC";
else
mx_internal::sortDirection = "DESC";
placeSortArrow();
}
}
You have to specifically call the placeSortArrow() method when you get the HEADER_RELEASE event and set the column index and direction information.
in the above code what does "this" refer to is it the datagrid because I am confused by this.query.SortField , I am assuming 'this' and "query' are your own custom objects. and why are you checking for count. what count is that.
Regards
-Mohan