Telerik RadGrid and RadComboBox filtering with a separate data class? - linq

I'm trying to implement a GridBoundColumn for filtering as described in this Telerik demo.
The example queries the database directly using SqlDataAdapter, but I want to use an existing class elsewhere in my project, and configure the DataSource of the filter RadComboBox in the RadGrid to use the LINQ data context common to the rest of my project.
namespace MyProject.DataLib
{
// Data context lives here.
}
namespace MyProject.UI
{
public partial class MyUI : PageBase
{
public class rgcFilterColumn : GridBoundColumn
{
...
protected void list_ItemsRequested(object o, RadComboBoxItemsRequestedEventArgs e)
{
using (MyProject.DataLib = new DataLib(CurrentUser)) // error CurrentUser
{
((RadComboBox)o).DataTextField = DataField;
((RadComboBox)o).DataValueField = DataField;
((RadComboBox)o).DataSource = ???; // LINQ would go here...?
((RadComboBox)o).DataBind();
}
}
}
}
}
The user defined by CurrentUser has the necessary credentials, however when I try to do this (which I know is wrong):
Cannot access non-static property 'CurrentUser' in static context.
What would be the best way to accomplish what I want here, as well as clarify my incomplete understanding of why I can't simply talk to my existing data context?

Found the solution, should've just looked around more closely.

Related

Dataview Delegate in Extension not executing

I am attempting to provide a Dataview delegate overide to the UnionDeductions view in PRCalculationEngine.cs
I note that this View does NOT have a defined dataview delegate in the Base graph - and the declaration is a bit 'different' in that is uses a BQL Fluent class.
Is this even possible to introduce a data view delegate in an extension
If so, Is there a different way of declaring the delegate ?
The business case is that the client needs to modify the Amount of the union deduction based on certain Employee attributes (length of service etc) and needs to dynamically modify the amount.
Due to the private and protected access of the GetBenefits and CalculateRegularBenefitNominalAmount methods, the only way I see to do this is to over-ride the dataview delegate and alter the Deduction/Benefit amounts prior to the calculation of the Benefit/Deduction amount...
public partial class PRCalculationEngine : PXGraph
{.....
public UnionDeductionQuery UnionDeductions;
...}
When I attempt to define a dataview delegate for this view in an Extension - I cannot get the dataview delegate to 'fire'
ie The code always just runs the .Select on the Base view but does not execute the delegate.
This is the core of the extension code
public class PRCalculationEngine_Ext1ESP : PXGraphExtension
{
public static bool IsActive() { return PXAccess.FeatureInstalled<FeaturesSet.payrollModule>(); }
#region Select Overrides
public PRCE.UnionDeductionQuery UnionDeductions;
protected System.Collections.IEnumerable unionDeductions()
{
foreach (PXResult<PREarningDetail, PRDeductionAndBenefitUnionPackage, PRDeductCode, EPEarningType> result in
UnionDeductions.Select())
{
// modify the package amount here...
yield return result;
}
}
#endregion
}
This is how the view is being called in the Base Graph
foreach (IGrouping<int?, PXResult<PREarningDetail, PRDeductionAndBenefitUnionPackage, PRDeductCode, EPEarningType>> resultGroup in UnionDeductions.Select(deductionCode.CodeID)
.Select(x => (PXResult<PREarningDetail, PRDeductionAndBenefitUnionPackage, PRDeductCode, EPEarningType>)x)
.GroupBy(x => ((PREarningDetail)x).RecordID))
{
Any advice or observations would be appreciated.
If the requirement is to overwrite the logic of the base dataview delegate which also references other protected methods, try if this helps:
First create an extension of the base class as follows with the PXProtectedAccess attribute and the methods that you want to override:
[PXProtectedAccess]
public abstract class PRCalculationEngine_FirstExt : PXGraphExtension<PRCalculationEngine>
{
[PXProtectedAccess]
public abstract DedBenAmount CalculateRegularBenefitNominalAmount(
PRDeductCode deductCode,
PREmployeeDeduct employeeDeduct,
PRPaymentDeduct paymentDeduct);
}
Then create a second extension (your actual graph extension) inheriting from both the base class and the first extension you created above.
public class PRCalculationEngine_Extension : PXGraphExtension<PRCalculationEngine_FirstExt, PRCalculationEngine>
{
// Here declare the view, write the PXOverride method, and access the protected methods of the base graph by referencing those as Base1.CalculateRegularBenefitNominalAmount()
}
Note that the above snippets are just to give an indication. I have not really worked on the PRCalculationEngine or tested that code but had done similar changes on a different graph to override the dataview delegate. Let me know if it helps. Thank you.

Automapper - How to map with dependency on current Session object

I am using Automapper within an ASP.Net MVC application to map DTO's to ViewModel objects.
in one of my mappings I need access to an object stored in the Session object.
public override void OnAuthorization(AuthorizationContext filterContext)
{
...
SecurityToken token = SecurityTokenFactory.CreateSecurityToken(userNode);
filterContext.HttpContext.Session[securityToken] = token;
...
}
In the constructor of my controller I set up the Automapper mapping.
Mapper.CreateMap<UserReportDTO, UserDefinedReportModel>()
.ForMember(dest => dest.IsEditable, opt=>opt.ResolveUsing(src => this.IsEditable(src)));
private bool IsEditable(UserReportDTO report)
{
if (this.GetCurrentUserToken().UserVisibilityLevel == VisibilityLevel.Root)
{
return true;
}
return false;
}
public JsonResult GetVisibleUserReports()
{
...
int ID = this.GetCurrentUserToken().UserId; //This works!
var reports = Mapper.Map < UserReportDTO[], UserDefinedReportModel[] >(inputarray); //This doesn't work
...
}
What happens is that the context.Session is null.
I'm guessing this is something to do with the way Automapper resolves the mapping - maybe a reference to one Context is set when the mapping is created, and then this Context no longer exists at mapping time?
How can I resolve the issue - is there a way to pass a parameter to a mapping operation?
My temporary workaround is to map all the other fields, and then manually loop through the mapped-collection, setting the field that requires the current context, but I'm loathe to keep this approach.
A couple thoughts that might put you on the right track:
Does it make any difference if you replace ResolveUsing with MapFrom? Both seem to accept a Func<TSource, TMember>, but perhaps there are subtle differences.
Would it be possible to turn your IsEditable method into an IValueResolver then pass the required session data into the constructor using AutoMapper's ConstructedBy() feature? Here's the relevant documentation. Scroll to the "Custom constructor methods" section.

Getting a reference to the AsCached property in the ObjectContext for Entity Framework 4.1

I have my ObjectContext exposed as a public property and am able to access it via my DBContext.
I want to enable caching for a drop down list. It requires the AsCached property. However, I can't get it to display in the intellisense. Do I need to include a specific namespace for it?
Here is my existing LINQ statement that I want cached.
IQueryable<Category> category = DbContext.Categories.Where(p => p.CategoryID > 0);
I'm tying to do something like this. Note though, that there is no intellisense when placing the "." after Objectcontext.
IQueryable<Category> category = DbContext.Objectcontext.Categories.AsCached.Where(p => p.CategoryID > 0);
The ObjectContext pops up in the intellisense, but not the AsCached property.
How can I get the AsCached property to appear?
Are you referring to the AsCached property described here Getting a reference to the AsCached property? In which case it seems to be an extension to the EF called linqtocache.
EDIT
I do not think you need to expose ObjectContext. Say you have a DbContext that looks like this:
public class DatabaseContext : DbContext
{
public DatabaseContext(string name) : base(name)
{
As = Set<A>();
}
public DbSet<A> As { get; private set; }
}
AsCached, in the context of linqtocache, is an extension method on IQueryable so in your code that calls it you can get access to the AsCached property by doing this:
using LinqToCache;
namespace MyApplication
{
class Program
{
static void Main()
{
var ctx = new DatabaseContext("ScalabilityTestEntities");
ctx.As.AsCached("Key").Where(p => p.CategoryID > 0);
}
}
}

mvvmlight - what's the "proper way" of picking up url parameters for a view model

I'm just switching a project across to mvvmlight and trying to do things "the right way"
I've got a simple app with a listbox
When an item is selected in the listbox, then I've hooked up a RelayCommand
This RelayCommand causes a call on an INavigationService (http://geekswithblogs.net/lbugnion/archive/2011/01/06/navigation-in-a-wp7-application-with-mvvm-light.aspx) which navigates to a url like "/DetailPage.xaml?DetailId=12"
The DetailPage.xaml is then loaded and ... this is where I'm a bit unsure...
how should the DetailPage get hooked up to a DetailView with DetailId of 12?
should I do this in Xaml somehow using a property on the ViewLocator?
should I do this in the NavigatedTo method?
Please feel free to point me to a full sample - sure this has been done a (hundred) thousand times before, but all the blogs and tutorials seem to be skipping this last trivial detail (focussing instead on the messaging and on the ioc on on the navigationservice)
Thanks!
The only place you can retrieve the URL parameter is in the view. So since your view is likely depending on it, you should fetch it in the OnNavigatedTo method.
Then, you should pass it along to your viewmodel, either using messaging (to expensive if you ask me), or by referring to your datacontext (which is the viewmodel I presume), and execeuting a method on that.
private AddTilePageViewModel ViewModel
{
get
{
return DataContext as AddTilePageViewModel;
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var postalCode = NavigationContext.TryGetKey("PostalCode");
var country = NavigationContext.TryGetStringKey("Country");
if (postalCode.HasValue && string.IsNullOrEmpty(country) == false)
{
ViewModel.LoadCity(postalCode.Value, country);
}
base.OnNavigatedTo(e);
}
I'm using some special extensions for the NavigationContext to make it easier.
namespace System.Windows.Navigation
{
public static class NavigationExtensions
{
public static int? TryGetKey(this NavigationContext source, string key)
{
if (source.QueryString.ContainsKey(key))
{
string value = source.QueryString[key];
int result = 0;
if (int.TryParse(value, out result))
{
return result;
}
}
return null;
}
public static string TryGetStringKey(this NavigationContext source, string key)
{
if (source.QueryString.ContainsKey(key))
{
return source.QueryString[key];
}
return null;
}
}
}
Create a new WindowsPhoneDataBound application, it has an example of how to handle navigation between views. Basically you handle the navigation part in your view, then set the view's DataContext accord to the query string. I think it plays nicely with the MVVM pattern since your ViewModels don't have to know anything about navigation (which IMO should be handled at the UI level).

Observer pattern on GWT

Hey there! I'm relatively new to both GWT and java programming (or OOP for that matter), so apologies for the beginner questions/mistakes in advance. I've been trying to create some kind of observer pattern, but the development mode console keeps dropping error messages and sadly, they're far from helpful.
So here's what I'm trying to achieve:
- I've got the model that consists of the class Country, and stores a value called Influence.
- The view is the class called CountryDisplay. It's a GWT widget that should always display the current influence of a given country.
public class Country {
private int influece;
private CountryDisplay display;
public Country() {
influence = 0;
}
public void setDisplay(CountryDisplay display) //...
public int getInfluence() //...
public void setInfluence(int value) {
influence = value;
display.update();
}
}
public class CountryDisplay {
private Country country;
public CountryDisplay (Country country) {
//GWT widget creating stuff
this.country = country;
}
public void update() {
//InfluenceCounter is a simple Label
InfluenceCounter.setText(Integer.toString(country.getInfluence()));
}
}
Then in the EntryPoint class I do something like this:
Country italy = new Country();
CountryDisplay italyDisplay = new CountryDisplay(italy);
italy.setDisplay(italyDisplay);
RootPanel.get("nameFieldContainer").add(italyDisplay);
italy.setInfluence(3);
The development console indicated that it had a problem with the line "display.update();" in class Country. My first guess was that the problem was that the display was not initiated, so I created an interface for it, and in the Country constructor I created an empty, new display, that would later be overwritten.
public Country() {
influence = 0;
display = new DisplayInterface() {
public void update() {}
}
}
But I had no luck this way either. I guess this kind of cross-referencing is not allowed? I mean that the view has the model as a variable and vice versa.
When calling a method on the view individually (like:
italy.setInfluence(3);
italyDisplay.displayTheCurrentValue();
) it works, so the problem is definitely in the observer logic.
If I understand correctly, your are trying to "bind" user interface elements (your view class CountryDisplay) to data (the model class Country). "Bind" in the sense that if you change the model data (for example, call italy.setInfluence(10)) then the view would automatically update itself to reflect the change. And if your view provided an editor, you want the "binding" also to work in the other direction.
There are several frameworks out there that achieve this, see for example the post Best data binding solution for GWT. I have used GWT Pectin and there is the GWT Editors framework (which I have not yet used myself as it is relatively new).
Looking at your code, I feel you might want to more clearly separate the model from the view: your model class (Country) should not know about the view class, that is, it should not store a reference to CountryDisplay.

Resources