module communication not working in DNN - c#

I am using DNN6 and i creted two modules and tried to connect between them using module communicator, here is my code:
#region IntermoduleCommunication
ModuleCommunicationEventArgs oArgs = new ModuleCommunicationEventArgs();
oArgs.Value = Session["ShoppingCart"];
if (ModuleCommunication != null)
ModuleCommunication(this, oArgs);
#endregion
but i am getting 'null' in the ModuleCommunication variable?

Are you wrapping the modules in an update panel, (have the supports partial rendering option enabled) in the DNN manifest?
If I recall correctly, IMC won't work via UpdatePanels.

From whatever code you have provided, it should work. In order to get help you need to provide code for both IModuleCommunicator and IModuleListener implementation. But you can review Example implementation here. Let me know if you need more help.
Also if you are not using latest version of dnn, please try testing it by creating of latest dnn instance. Let me know if you need more help.

To get this working you need to implement the IModuleCommunicator interface. Right click on the IModuleCommunicator as showed below and extract the interface.
public partial class MyClass: PortalModuleBase, IModuleCommunicator
once extracted the following will be generated
public event ModuleCommunicationEventHandler ModuleCommunication;
I call it from a button click event
protected void btn1_Click(Object sender, EventArgs e)
{
if (ModuleCommunication == null) return;
ModuleCommunicationEventArgs args = new ModuleCommunicationEventArgs();
args.Sender = this.GetType().ToString(); ;
args.Target = "MyTarget";
}
wrap the whole thing in a try catch block to catch exceptions......hope this helps

The answer here is simple, you've forgotten exactly how events work, they are just like any other object, you have to instantiate them. aka.
public event ModuleCommunicationEventHandler ModuleCommunication = new ModuleCommunicationEventHandler(SomeStaticMethodThatWillBeCalledByDefault);

Related

Switch between multiple windows

We have a software system that should support multiple variants. Each variant should contain a customized version of one or more UI components (Windows Forms in this case).
A prototype has been created in VS2017 and has the following solution;
ProductFoo (Solution)
MainApplication (Windows Application)
MainApplicationForm1.cs (Windows Forms)
XY1 (Class library)
Form1.cs ((Windows Forms)
XY2 (Class library)
Form1.cs ((Windows Forms)
In this simple prototype, the MainApplicationForm1 forms contain one button that when clicked should either show Form1.cs in XY1 og XY2 library depending on which variant is selected.
To solve this we have updated Solution Manager with following solution configurations;
XY1_Debug
XY1_Release
XY2_Debug
XY2_Release
Then we added conditional compilation symbols for MainApplication.
The solution configurations XY1_Debug and XY1_Release use the conditional symbol XY1
The solution configurations XY2_Debug and XY2_Release use the conditional symbol XY2
Then we added reference from MainApplication to both XY1 and XY2 projects.
Lastly, we added the following code in MainApplicationForm1.cs
public partial class MainAppForm1 : Form
{
public MainAppForm1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
#if XY1
XY1.Form1 form = new XY1.Form1();
form.ShowDialog();
#elif XY2
XY2.Form1 f1 = new XY2.Form1();
f1.ShowDialog();
#else
#error The MainApplication is missing Form1
#endif
}
}
This solution works but I have reservations with using preprocessor directives. The code looks messy and can quickly become difficult to maintain. What are the best practices for this kind of scenario?
Appreciate any input.
Your question is quite broad and referes to the base structure of the project you want to have.
The way you choose is close to the Feature toggling, just done based on the build configuration. Ususaly it sould be something like:
if(features.IsOn("XY1-feature")){
XY1.Form1 form = new XY1.Form1();
form.ShowDialog();
}
Classical way can give you more flexibility. E.g. moving feature toggless to the config would give you a possibility to dynamically toggle different features for specific deployment, but, as impact, it would encrease the complexity and would require more testing
I would suggest you to take a deeper look into Dependency injection and Strategy pattern
As an alternative to the Feature toggling you can use branching. Create a specific branch for the specific project/client. That could bring you problems with merging, but would keep your cleaner for a specific implementation. It would fit best to the project with lots of minor differences from project to project
I suggest using two radio buttons to solve this problem. This is a very easy way.
Select radioButton1, pop up XY1.Form
Select radioButton2, pop up XY2.Form
MainApplicationForm1.cs:
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (radioButton1.Checked)
{
XY1.Form1 form = new XY1.Form1();
form.Show();
}
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
if (radioButton2.Checked)
{
XY2.Form1 f1 = new XY2.Form1();
f1.Show();
}
}

Dynamically run C# code from a string, in the context of the current form (code)

I need to run code from a text file, in the context of the current form (code). One of the requirements is to have the code create and add a new control to the current form.
For example, in Form1.cs:
using System.Windows.Forms;
...
public int[] someCoords = { 20, 10 };
public string someImportantString = "Hello";
public void SayHello() {
MessageBox.Show("Hello world.");
}
private void runCodeInForm() {
// theCode will be read from a text file
string theCode = #"
// Has System.Windows.Forms already added in form
Button newButton = new Button();
newButton.Text = someImportantString; // Hello
newButton.Location = new Point(someCoords[0], someCoords[1]); // 20, 10
// Add this button to the current form
this.Controls.Add(newButton);
this.SayHello(); // Says hello. Just an example function.
";
// Execute theCode in the current form
CodeRunner.Execute(theCode, this);
}
I have tried using CSharpCodeProvider, but it seems like this can only compile the code as a separate program.
I would like this because I want the user to be able to change this code (text file) to what they would like. It is not specifically just for creating controls, but that functionality will be needed.
I am not worried about the security of the program.
Consider these points to solve the problem:
You should create your dynamic code as a class in a dll.
Your class should implement a specific interface or have a known method like Run. So you can call the method later when the code compiles.
Your class or the known method should accept some parameters to receive the context variables. These context variables can include a Form as parameter. You can also encapsulate context parameters in a class/interface or to keep it simple you can rely on dynamic for passing parameters.
Then to run the dynamic code, first compile it, then pass context parameters to the class or the known method and call the known method.
Example
Here is a quick and dirty example of how you can compile and run a code at run-time and let the code use your context:
public string SomePublicField = "Hello!";
private void button1_Click(object sender, EventArgs e) {
var csc = new CSharpCodeProvider();
var parameters = new CompilerParameters(new[] {
"mscorlib.dll",
"System.Windows.Forms.dll",
"System.dll",
"System.Drawing.dll",
"System.Core.dll",
"Microsoft.CSharp.dll"});
var results = csc.CompileAssemblyFromSource(parameters,
#"
using System.Windows.Forms;
using System.Drawing;
public class Sample
{
public void DoSomething (dynamic form)
{
var b = new Button();
b.Text = form.Text;
b.Click += (s,e)=>{MessageBox.Show(form.SomePublicField);};
form.Controls.Add(b);
}
}");
//Check if compilation is successful, run the code
if (!results.Errors.HasErrors) {
var t = results.CompiledAssembly.GetType("Sample");
dynamic o = Activator.CreateInstance(t);
o.DoSomething(this);
}
else {
var errors = string.Join(Environment.NewLine,
results.Errors.Cast<CompilerError>().Select(x => x.ErrorText));
MessageBox.Show(errors);
}
}
Basically what it seems you want to do, is dynamically compile and add code to your current program. This is not impossible and there are various ways to do it.
The most common uses for this type of functionality are plugins and scripting systems. However there are caveats with the both of these.
One of the of the biggest draw backs is that to run code that you have compiled (however it is you are doing that), you need to literally load it as an assembly into you app domain using the standard, Load methods. Once a library is loaded you actually cant unload it with out unloading the app domain, so this creates problems in certain situations .
If this is a scripting thing you are after, i would seriously consider using a pre-built scripting library (and there are many). Some use nifty-tricks to make this work well and have done a lot of the hard work for you... As an example http://csscript.net/
However be prepared! plugin and scripting systems start off easy, yet they are incredibly fiddly to make stable and workable. I would suggest exploring the domain of your problem first, and make sure you are not trying to reinvent the wheel... There are many options for serialisation and loading object parameters at run-time safely without fuss
Good luck

How to call Javascript function from activex or dll

I found the similar questions how to call java script function from activex or dll in c# but this is not provide me solution.than i continue my searching finally i got msdn link on this
http://msdn.microsoft.com/en-us/library/ms171712.aspx
To access DOM from a UserControl hosted in Internet Explorer
Create your own custom derived class of the UserControl class. For more information, see How to: Author Composite Controls.
Place the following code inside of your Load event handler for your UserControl:
HtmlDocument doc = null;
private void UserControl1_Load(object sender, EventArgs e)
{
if (this.Site != null)
{
doc = (HtmlDocument)this.Site.GetService(typeof(HtmlDocument));
}
}
Unfortunately I am still unable to get DOM object in my class.I have try to see what i get in this.Site so i put it on a messagebox
MessageBox.Show(this.Site.ToString());
which shows me strange thing that is
System.Windows.Forms.Control+AxSourcingSite
please help me..

Is there anyway to call a function in a class that inherits from system.web.ui.page from a mvc3 controller?

I have a cs file delivered from a vendor with a structure like the following:
public partial class Test : System.Web.UI.Page
{
public void InsertSignature()
{
Response.Write("ASDFASDFAF#WRRASDFCAERASDCDSAF");
}
}
I am attempting to use the InsertSignature function in a MVC 3 application using the following code
MySample sample = new Test();
sample.InsertSignature();
I'm getting the following HttpException: "Response is not available in this context." Is there anyway that this can work with out modifying the vendor delivered product. I know there are ways to make this work by modifying the file but if at all possible it would be great to avoid doing this.
Thanks in advance.
It seems as a known issue (Response is not available in this context)
Just replace
Response.Write("ASDFASDFAF#WRRASDFCAERASDCDSAF");
with
HttpContext.Current.Response.Write("ASDFASDFAF#WRRASDFCAERASDCDSAF");
and this will do the trick. It doesn't seem as a big change.
UPDATE: If you wish to prevent the code from rewriting with future updates, just rename the method - e.g. from InsertSignature() to InsertSig(). If the file is being updated with the vendor's version, it will simply not compile, and will be clear what the reason is.

How to make work UIDocumentInteractionController in MonoTouch

I am trying to open a *.epub file throught my application and I don't quite understand how to make it with the UIDocumentInteractionController class. I have seen the official IOS documentation and examples and some of the examples over the net but I don't understand how that class works. This is how I do it, what I achieve and what I dont understand:
I have a UIView with a UIButton:
using MonoTouch.UIKit;
using MonoTouch.Foundation;
using System.Drawing;
public class MyView : UIViewController
{
UIButton myBtn;
public MyView() :base()
{
View.Frame = new RectangleF(0,0,1024,768);
var myRect = new RectangleF(300,300,100,50);
myBtn = UIButton.FromType(UIButtonType.RoundedRect);
myBtn.Frame = myRect;
myBtn.TouchUpInside += delegate
{
var dic = UIDocumentInteractionController.FromUrl(new NSUrl("http://192.168.50.50:2020/myfile.epub"));
var dicDel = new UIDocumentInteractionControllerDelegate();
dic.Delegate = dicDel;
InvokeOnMainThread(delegate
{
var result = dic.PresentOpenInMenu(myRect, View, true);
//If I do this -> NullReferenceException because delegate is null (something about autorelease?? Don't know)
if(!result) dic.Delegate.DidDismissOpenInMenu(dic);
});
}
}
}
The weirdest thing is if I debug and inspect "dic" (without the delegate) before calling the PresentOpenInMenu() method it shows the menu (returning true) but just after doing it the app blows up on Main.cs because the autorelease thing I dont understand.
I am a little lost. Can someone help me understand this class and how can I make it work correctly? Thanks in advance.
EDIT: By the way, I used a *.txt file too with same results.
It looks like a MonoTouch bug. Setting the UIDocumentInteractionController.Delegate (or WeakDelegate property and then querying its value returns null (which will fail later on).
I'll look into this bug and update this answer if I can provide a workaround (until the bug is properly fixed in a future release of MonoTouch).
UPDATE: UIDocumentInteractionController already creates it's own internal UIDocumentInteractionControllerDelegate so you do not need to create one. The Delegate methods, like DidDismissOpenInMenu are available as events on UIDocumentInteractionController itself.
Remove your own Delegate (creation and set) and use the events and you should be fine.
UPDATE #2: The Delegate property returns null since the default UIDocumentInteractionControllerDelegate is not usable as is. It is meant to be inherited from and customized to do what you want to (and the unusable default one is not registred properly to be used). E.g.
class MyDocumentInteractionControllerDelegate : UIDocumentInteractionControllerDelegate { }
and
var dicDel = new MyDocumentInteractionControllerDelegate ();
would work, as in no NullReferenceException, but of course DidDismissOpenInMenu won't be doing anything interesting.

Categories

Resources