I am using DevXpress XtraReport v13.1
I have a dateTime parameter that I would like its default value to be current Day whenever it is used.
When I leave the value of the parameter empty. it is understood by DevExpress as 1/1/0001 !!!
It is important for me because the parameters will be applied as a filter to a database and I require to decrease the probability that user can fetch too much data from the database (that may affect the performance)
Anyone have an idea of how to do that?
I just did It Like this
public Report()
{
InitializeComponent();
this.Parameters[0].Value = DateTime.Today;
this.Parameters[1].Value = DateTime.Today;
}
the Approach AbdelRahman Shabana took Fails because the Event fires Again when user Clicks Submit, Just Give A look Here
Thanks for all who gave me hints.
I managed to solve my problem programatically by responding to event : ParameterRequestBeforeShow
Then the report will be shown with today's date as default value for parameters and user is still allowed to select different date.
private void XtraReport1_ParametersRequestBeforeShow(object sender, DevExpress.XtraReports.Parameters.ParametersRequestEventArgs e)
{
this.Parameters["StartIssueDate"].Value = DateTime.Now;
this.Parameters["EndIssueDate"].Value = DateTime.Now;
}
There is a discussion with a solution in the DevExpress Support Center.
One of those solutions is to create your parameter as a nullable DateTime? but then it is more complicated to bind to the XRControl.
Related
I'm making a website that pulls some information from a SQL DB.
I have made a Model for validating that i have the information i need before i try the query. This means (if things go right) the method will always resolve and the Model.IsValid will be true. The query is to get all rows between two given dates.
Now comes my problem - When it gets into the ActionResult where it calls the query i first want to check if the amount of rows returned is less than 1000.
If it is < 1000 i want it to show the view with the rows, however if it's greater than 1000 i want an error message to be displayed that tells the user to narrow the search criterias.
I might be going about this the complete wrong way, and my initial idea was to "simply" change the validator to no longer being valid. Which would the automatically trigger the error message from the model. After searching around though that doesn't seem to be a possibility.
Anyone got some ideas how to go about this? Am completely wrong about my approach?
ValidatorModel:
public class DateValidator
{
[Required]
public DateTime StartDateTime { get; set; }
[Required]
public DateTime EndDateTime { get; set; }
}
ActionResult:
public ActionResult GetListFromDateRange(DateValidator validator)
{
RangeParent parent = new RangeParent();
if (ModelState.IsValid)
{
int queryCount =
repository.GetCountFromDateRange(validator.StartDateTime,
validator.EndDateTime);
if (queryCount < 1000)
{
parent.Meters =
repository.GetListFromDateRange(validator.StartDateTime,
validator.EndDateTime);
return View(Constants.ViewNames.DisplayRangeData, parent);
}
else
{
//display error message telling user to narrow the datetime range
return new EmptyResult();
}
}
return View(Constants.ViewNames.IndexView);
}
And last the two queries i currently use:
public List<Meter> GetListFromDateRange(DateTime startDateTime, DateTime endDateTime)
{
using (dbContext = new HeatDataVerifEntities())
{
return dbContext.Meters.Where(p => p.Created >= startDateTime && p.Created <= endDateTime).OrderBy(p => p.Created).ToList();
}
}
public int GetCountFromDateRange(DateTime startDateTime, DateTime endDateTime)
{
using (dbContext = new HeatDataVerifEntities())
{
return dbContext.Meters.Where(p => p.Created >= startDateTime && p.Created <= endDateTime).Count();
}
}
Another thing i considered was to create another ActionResult that runs the check for the row size which i would call instead of 'GetListFromDateRange' - and then have that either return an empty partial view along with calling the method for getting the list of item, or returning a partial view that has an error message in it. It just seemed like the should/could be an easier or smarter solution to that.
Again i have been searching around, but as i also mentioned i might simply just be looking at this wrong.
Thanks in advance.
Displaying around 1000 records on one page is not exactly useful, plus it affects many things, such as the performance of your database, depending on how many users request data at the same time, how fast the website displays the data to the users and ultimately your website might crash completely if too many sets of data are requested at the same time.
Instead, why don't you simply add pagination? Decide on a page size, say 20, return those records from your query, together with the number of pages required to display all data. You can then use that to build the page pagination itself. So you never return more than 20 rows from your db, the pressure is minimal, the site runs quickly.
The way you are going now, you are requesting a lot of data, and if you have more than 1000 records all you do is display an error message expecting the user to make another request. You already have the data though, but you're not using it for anything other than a count. Unless a course, all you do is run a count first and then if less than 1000 then you run the actual query.
Model validation is run on inputs, not outputs and I wouldn't suggest you try to change the way MVC works, just to fit a specific scenario which shouldn't happen anyway.
If you want to crack on with your idea then run the count query first, if result is over 1000 then return an error message and display that to the user. You can do this without any kind of custom, non-model validation.
You can always add a custom error message that will show up in ValidationSummary
ModelState.AddModelError(string.Empty, "My own error message");
I'm trying to create my calendar control with databinding.
public partial class Calendar : UserControl
{
public static readonly DependencyProperty DateProperty =
DependencyProperty.Register("Date", typeof(DateTime),
typeof(Calendar), null);
public object Date
{
get { return GetValue(DateProperty); }
set
{
SetValue(DateProperty, value);
OnPropertyChanged("Date");
}
}
public Calendar()
{
// Required to initialize variables
InitializeComponent();
DayText.Text = ((DateTime)Date).ToString("dd");
MonthText.Text = ((DateTime)Date).ToString("MMM");
this.Loaded += new RoutedEventHandler(Calendar_Loaded);
this.GotFocus += new RoutedEventHandler(Calendar_Loaded);
}
void Calendar_Loaded(object sender, RoutedEventArgs e)
{
DayText.Text = ((DateTime)Date).ToString("dd");
MonthText.Text = ((DateTime)Date).ToString("MMM");
}
}
But When I create the listbox with this control, same calndar have the wrong date. I'm sure that the Date passed thorough databinding is correct but I don't understand why same calender show a different day (I'm noticed that is the day of a previous calendar control intance)
Thank you for supporting!
Hmm ... where do we start? Here's a few things I've noticed:
If you're using a dependency property, there's no need to call OnPropertyChanged from the Date property setter.
The dependency property declares the type as DateTime, but your public exposed property is of type object, which then requires you to cast it elsewhere.
If Calendar_Loaded is to be called in more situations than in response to the Loaded event (such as the GotFocus event, then I'd recommend that you call it something else, or create a method with a relevant name (e.g. UpdateDateParts) and call it from properly named separate event handlers.
Using fixed format specifiers when processing date strings does not localize well.
In addition to that, I'd suggest that you could implement the user interface in a manner that supports databinding (and re-templating) by using bindings and exposing the date parts of the Date dependency property instead of manually updating the Text property of some text blocks/boxes in event handlers. In fact, if you derive from Control instead of UserControl then you can create and actuall lookless control that has it's user interface defined by a style in themes\generic.xaml that can be re-defined by users of your control.
As for why the date is incorrect in different instances of your calendar control, we'd need to see some of your XAML/code to see how the control is being used and initialized to be able to provide a better answer. However, I thought the above was worth putting in an Answer, instead of trying to say it in a Comment.
This is a bit of a hypothetical question that has sent me off down the garden path... Say I have a gridview that I'd like to edit... given a method that binds the data..
private void BindGridFirst() {
var data = new List<string>() {
"A","B","C","D","E","F"
};
gridView.DataSource = data;
gridView.DataBind();
}
Now presume that I'm looking at this page, and another user has come along and made some changes to the underlying data, and I now go and click the edit button to edit D...
The edit method is pretty straight forward:
protected void RowEdit(object sender, GridViewEditEventArgs e) {
gridView.EditIndex = e.NewEditIndex;
BindGridSecond();
}
Edit: I feel compelled to point out, that this method is used in pretty much all the online examples, including ones from Microsoft.
This BindGridSecond() method looks like so:
private void BindGridSecond() {
var data = new List<string>() {
"A", "AA", "B","C","D","E","F"
};
gridView.DataSource = data;
gridView.DataBind();
}
It's exactly the same, but the data is now changed. Once the UI updates, the user is now in edit mode against row C.
Not what the user expected or wanted. How should this scenario be handled to avoid such an issue?
Personally, I use the DataKeyNames property and the SelectedDataKey on the GridView, so that I can easily obtain the primary key of the row the user wants, rather than relying on the index of the grid.
By using the primary key, you don't have any issues with new items being added to the collection, such as in your example. Plus, using the primary key makes it easier to deal with paging on the grid, as you don't have to take the page number and index into account.
Imho there are two options:
You could cache the Data you want to bind to the Grid in a Session for example. So you are able to check for changes before you call the BindGridSecond-Method and alert the user if any changes have been made while he was browsing the Page.
In option 2 you would again cache the Data you were binding in the BindGridFirst-Method and just work with this data for the next PostBack actions. So you don't have to worry about changes that may occur while browsing the Grid.
I thought this was a simple problem, but I can't find any information on the web. I'm binding a ListBox to a List using BindingSource like so:
List<Customer> customers = MyMethodReturningList();
BindingSource customersBindingSource = new BindingSource();
customersBindingSource.DataSource = customers;
customersListBox.DataSource = customersBindingSource;
Now, when I add or delete from customers list, my ListBox gets updated (even without using ResetBindings on BindingSource), but if I change any of the customer objects in the list, it does not. Calling ResetBindings has no effect. I even implemented my own BindingList, but the behaviour hasn't changed.
The Customer class uses properties for accessing and modification of data. Its ToString() content is displayed in the list.
I'm using C# in .Net 2.0.
Any ideas?
Thanks
If you use a BindingList you don't even need the BindingSource:
BindingList<Customer> customers = new BindingList<Customer>(MyMethodReturningList());
customersListBox.DataSource = customers;
OK, here's a dirty fix: wenever you need to refresh the box contents set datasource = null, then rebind it.
the reason it doesn't update is because the objects in the list haven't changed and it only checks the refrences of the object rather than their contents.
There is also a bug in the list box which can cause this problem. If you set the SelectionMode to None this problem appears.
As a work around I set the selection mode to One and then back to None when updating the datasource.
I got around this problem by converting data to array when updating source. Please see UpdateData method. This way you can update your combo box without losing ComboBox Settings.
class Person {
public int Id {get; set; }
public string FirstName{ get; set; }
public string SurName {get; set; }
}
public Form1()
{
InitializeComponent();
comboBox1.DisplayMember = "FirstName";
comboBox1.ValueMember = "Id";
comboBox1.DataSource = m_PersonList;
}
public void UpdateData() {
m_PersonList[0].FirstName = "Firstname1";
comboBox1.DataSource = m_PersonList.ToArray<Person>();
}
I understand that this question was asked almost 6 years ago but other than work-arounds I do not see a correct answer here.
When you change property of an item in a collection the event gets raised for the element (object) but not the collection. So the collection does not see a change and will not refresh bound controls. Elements inside all binding collections and most generic collections like List<> receive 2 events, PropertyChanging and PropertyChanged. When a property of the element inside collection is changed, the event gets triggered. All you need to do is add an event handler that would trigger either re-binding or raise an event on the Collection.
I'm updating one object, and trying to update any child objects along with it.
Basically I'm handling the OnUpdating event of a LinqDataSource.
In the DataContext class I have the ObjectUpdate function (where right now I've just got a breakpoint so I can see the values...)
In the LinqDataSource.OnUpdating event e.NewObject.Child is null, which makes no sense whatsoever. I set that to a new value, but by the time I get to DataContext.ObjectUpdate NewObject.Child has been overwritten with the OLD value...
So somewhere between LinqDataSource.Updating and DataContext.UpdateObject it's populating the object with the old values... but I need the new ones.
Is there a way to fix that, or am I going to have a nervous breakdown?
I think I figured out the problem. After running LinqDataSource through .NET Reflector I noticed that:
1) It's the LinkDataSourceUpdateEventArguments.OriginalObject which is actually attached to the data context
2) values are copied from the NewObject into OriginalObject after OriginalObject is attached to the data context
What I don't understand is why the association properties are not copied. Maybe for the same reasons you can't serialize them?
The workaround is/was to handle the Updating event myself and do the actual submit instead of letting LinqDataSource handle that part.
void FormDataSource_Updating(object sender, LinqDataSourceUpdateEventArgs e)
{
var newObj = e.NewObject;
var table = FormContext.GetTable(e.NewObject.GetType());
if (BuildingObject != null)
BuildingObject(sender, new HeirarchicalBuildObjectEventArgs(newObj));
table.Attach(newObj, e.OriginalObject);
FormContext.SubmitChanges();
e.Cancel = true;
}