Delegates in C# - reflection

How to add a method to delegate Using reflection? Let us consider im having two assemblies,one AAA contains the definition of delegates and another one BBB contains the method to be added to the delegate.In BBB i have add the method to the delegate in AAA.How to accomplish this scenario?

Something like this (warning - not compile tested):
// get the methodinfo for the method you want to add
MethodInfo methodToAdd = typeof(AAA).GetMethod("MyMethod");
// create a delegate instance for it
Delegate methodDelegate = Delegate.CreateDelegate(typeof(BBB.MyDelegate), methodToAdd);
// get the event you want to add to
EventInfo eventToAddMethodTo = typeof(BBB).GetEvent("MyEvent");
// call the event's add method, with the delegate you want to add
eventToAddMethodTo.AddEventHandler(null /*or the AAA instance if this is a non-static event */, methodDelegate);
If it's not an event you want to add to, but just another Delegate, then you use Delegate.Combine:
Delegate combinedDelegate = Delegate.Combine(oldDelegate, methodDelegate);

Related

Creating a Xamarin.Forms.DataTemplate from a view function

A CollectionView (or ListView) provides a way to view a sequence of objects (of type T). It has the advantage, compared to a StackLayout or Grid, that views are only loaded as needed.
The natural way to specify the view for each object would be to provide a function v:T->View (F#).
However CollectionView/ListView expects a DataTemplate. The DataTemplate class is very tied to bindings and as such the API is unnatural, uninformative and type-unsafe. The useful property seems to be Values with type IDictionary<BindableProperty,Object>.
Is it possible to work around this API and make a function which takes a v:T->View and returns a DataTemplate? This would allow making a clean API for DataTemplate and therefore for ListView and CollectionView.
One way to achieve this would be to create your own DataTemplate and ViewCell.
DataTemplate only requires a type deriving from ViewCell to instantiate when needed by the ListView.
It then calls the OnBindingContextChanged method of this newly created/reused ViewCell and passes the corresponding value of the element.
At this moment, you have access to the ViewCell.View property which will contain the control you want to display.
You can execute your function at that time.
In your case, since you have a list of 'T, this would be something like this:
type FuncViewCell(createFunc: 'T -> View) =
inherit ViewCell()
override x.OnBindingContextChanged () =
let data = x.BindingContext :?> 'T
x.View <- createFunc data
type FuncDataTemplate(createFunc: 'T -> View) =
inherit DataTemplate(fun () -> FuncViewCell(createFunc))
(...)
let createViewForData data =
Button(Text = data.Text)
let listView = ListView()
listView.ItemTemplate <- FuncDataTemplate(createViewForData)
listView.ItemsSource <- dataSource
----
Or even directly:
type FuncListView(createFunc) =
inherit ListView(DataTemplate = FuncDataTemplate(createFunc))
let listView = FuncListView(createViewForData)
listView.ItemsSource <- dataSource
A similar approach can be found in Fabulous.XamarinForms.
The difference is that the element comes with its own view creation function. So there is no need to extend DataTemplate to pass a function.
https://github.com/fsprojects/Fabulous/blob/79c5df748fff7a108dfbcbf8609cb2265a8fddc7/Fabulous.XamarinForms/src/Fabulous.XamarinForms.Core/CustomControls.fs#L110-L151
the solution would be to use DataTemplateSelector.
Here is the link for this:-
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/data-templates/selector
What you can do is get a DataTemplate Id from an API call and based on the Id you can select that particular DataTemplate. You will have make that many DataTemplates and store in the Xaml of the Page. This would be the most safest and easiest solution.

Passing parameters of dynamics ax

On Dynamics AX 2012,Passing between two step form a parameter that I would use to change the data source of the second form;
how you pass a parameter from the init form to init the data source?
I hope I have understood the question
If you wanto to pass a parameter between forms, you have multiway.
One solution.
In Form - A override a method clicked() control Button
void clicked()
{
Args args;
FormRun formRun;
;
args = new Args();
args.name(formstr(nameyourFormB));
args.record(nameTableSourceRecords);
args.caller(element);
formRun=new FormRun(args);
formRun.run();
formRun.wait();
}
So , in the SecondForm - Form - B
override method init()
public void init()
{
super();
if(element.args() && element.args().record() &&element.args().record().TableId == tableNum(nameSourceRecords))
{
nameTableSourceRecords = element.args().record() ;
stringEdit.text(nameTableSourceRecords.nameFieldTableSourceRecords);
}
}
You have to insert in Designs node Form-B a one StringEdite (set AutoDeclaration YES) in Properties.
Now, you open Form-A select a record, click on control Button -> will Open Form-B and you have set a value in your StringEdit control.
I hope to help you.
Greetings!
Get the parameter in the form.init(), save it to a variable in your form's classdeclaration, then override the datasource's init() method and manually create a FormDataSource object using the passed in parameter to determine the datasource.
Although I'm not sure how you're going to show this on form controls...the controls will expect the datasource to be what it is set up as. There's probably a better way to achieve whatever you're trying to do.
One solution of this is to use EnumTypeParameter and EnumParameter property on menuitem of child form. Set these parameter value on parent form and on child form init you just need an if clause then. like:
if (args.parmEnumType() == yourEnum && args.parmEnum() == 'yourEnumValue')
{
//set the desired datasource
}
these links may help you:
opening a form on basis of menuitem
and
xArgs.parmEnumType

Calling Generic-HttpHandler inside another Generic-HttpHandler

I want to call a genric http-handler inside another generic-http-handler Inside the same project.
Suppose I have to two handlers
FirstHanlder.ashx
SecondHandler.ashx
I want to call the second on SecondHandler.ashx on the FirstHandler.ashx
I created an instance of SecondHandler.ashx on the FirstHandler.ashx as follows
var objCreateLogs=new SecondHandler();
objCreateLogs.ProcessRequest(context);
I want to know will it work?
1. Further more do I need to pass the `**context**` or it will be implicitly there.
How Can I get response of the SecondHandler.ashx on the FirstHandler.ashx since the return type of ProcessRequest is void.
Can I get response from httpcontex
Thanks.
The handlers should not do the work. Create a Class/Method that does the word and use it in both handlers.
//Extract parameters
string par1=Request["a"];
//...
//Call a backend function
var result = MyFunctions.DoTheWork(par1);

Cannot use GetLocalResourceObject inside InstantiateIn

I'd like to localize my aspx-page.
This should include dynamically created LinkButtons in a GridView inside of InstantiateIN
(amendment 1: implementation of the System.Web.UI.ITemplate.InstantiateIN method to manipulate the appearance of a GridView)
(amendment 2: first six lines of code added to better indicate location of other code)
But inside InstantiateIN I cannot use (see) the method GetLocalResourceObject
Solution: use a Session-Variable
Question: Why can't I use GetLocalResourceObject inside InstantiateIN?
the following happens inside InstantiateIN
public class DynamicTemplateGridViewSearch : ITemplate
{
public void InstantiateIn(System.Web.UI.Control Container)
{
switch (ItemType)
{
case ListItemType.Item:
switch (InfoType)
{
case "Command":
{
LinkButton search_button = new LinkButton();
search_button.ID = "search";
search_button.CommandName = "Edit";
//following line does not work. Error is:
//The name 'GetLocalResourceObject' does not exist in the current context
search_button.Text = GetLocalResourceObject("SearchButtonResource1.Text").ToString();
//so I have to create a Session-String in Page_Load
//which is referenced here
search_button.Text = (string)new Page().Session["SearchText"]; // "Search";
search_button.Click += new EventHandler(search_button_Click);
Container.Controls.Add(search_button);
You haven't told where exactly InstantiateIn method is located - is it inside an custom control?
Regardless, you can use container.Page property to get reference to page object and invoke the method on it. For example,
search_button.Text = Container.Page.GetLocalResourceObject("SearchButtonResource1.Text").ToString();
BTW, session object reference can be obtained similarly or you may use current HttpContext. For example, Container.Page.Session["SearchText"] OR HttpContext.Current.Session["SearchText"]

Flex: Nested tags in MXML == run method.... how to set this up?

I have a class called JDChart, and a class called JDLine. Inside JDChart there is a method called addLine() that expects 1 parameter of type JDLine. This is all good. but I want to be able to put this in XML Like this:
<JDChart>
<JDLine/>
<JDLine/>
<JDLine/>
</JDChart>
And for each JDLine nested in a JDChart in the MXML, I want the addLine() method to be called on the JDChart with the respective JDLine passed.
Does what I want to do make since? I am not sure how to set this up? I am assuming I have to use meta tags on the JDChart class somewhere to tell the compiler to do this? Does anyone know?
Thanks!!
I believe when you add things in MXML like that it will just construct them and then call addChild().
You could have JDChart override addChild(), and check the type of what's being added. If it's a JDLine you can then pass it to your addLine() method before passing it along to super.addChild().
If JDLine objects are going to be parented only by JDChart objects, use this.
In the added event handler of the JDLine class, add the following code:
public function onAdded(e:Event):void
{
var chart:JDChart = this.parent as JDChart;
if(!chart)
throw new Error("Parent is not JDChart");
chart.addLine(this);
}

Resources