Setting action from function parameter is null - c#

I have some actions in a view.
public class AView
{
public Action Show { get; set; }
public Action Hide { get; set; }
}
and I'm trying to set those actions inside another class, by passing them as a parameter (I don't want to pass the whole class)
_reloader.SetupActions(Show, Hide);
Reloader is abstract, because there might be different ways of handling how Hide/Show must behave depending on the scenario we're in.
public abstract class Reloader : IReloader
{
public void SetupActions(Action show, Action hide)
{
show = Show;
hide = Hide;
}
protected virtual void Show() { ... } //what should be done when Show is invoked
protected virtual void Hide() { ... } //same for Hiding
}
And for the current view, I might be using a RapidReloader, SafeReloader, etc. This bit is irrelevant, except that the injected reloader is specific to the current view.
Now my problem is simple and logic : when I'm in SetupActions, all parameters are null (because Actions haven't been set), and setting Show into null obviously does not work.
What can I do so that when Show.Invoke() happens my view, the ShowCode from the relevant reloader is called? I would like to avoid passing the whole view as a parameter.
Also, if you have a better design, I'm all ears. We might be in an XY problem situation

You will need to use System.ValueTuple nuget package if you don't use .Net Framework 4.7 or newer.
public interface IReloader
{
(Action Show, Action Hide) GetActions();
}
public abstract class Reloader : IReloader
{
public (Action Show, Action Hide) GetActions()
{
return (Show, Hide);
}
protected virtual void Show() { }
protected virtual void Hide() { }
}
public class FastReloader : Reloader { }
public class AView
{
public Action Show{ get; set; }
public Action Hide{ get; set; }
public void IwantTheNewActions()
{
var reloader = new FastReloader();
var actions = reloader.GetActions();
Show = actions.Show;
Hide = actions.Hide;
}
}

Related

Triggering "CanExecute" on postsharp [Command] when a document changes?

I am currently migrating a project to PostSharp to remove a lot of boilerplate code, most of it is going very smoothly but I'm left confused about how to force a command to recheck if it CanExecute. I expected PostSharp would inspect the command like it does properties to check for dependencies, here is a minimalist sample
[NotifyPropertyChanged]
public class MyWindowViewModel
{
/// Anything bound to this refreshes just fine as expected
public ObservableCollection<SomeType> Documents = new ObservableCollection<SomeType>();
[Command]
public ICommand AddDocumentCommand { get; set; }
public void ExecuteAddDocument () { Documents.Add(new SomeType()); }
[Command]
public ICommand CloseDocumentCommand { get; set; }
public bool CanExecuteCloseDocument () => Documents.Any();
public void ExecuteCloseDocument () { Documents.Remove(Documents.Last()); }
}
At start the collection is empty and the button attached to the close command is greyed as expected, however adding a document through the button attached to AddDocument doesn't activate the close document button, what is the appropriate way to accomplish what I need? Is PostSharp only considering assignments and not method calls as changes or is it something else entirely?
According to their Command documentation
CanExecuteCloseDocument should be a property
public bool CanExecuteCloseDocument => Documents.Any();
The method option is used when the command requires parameters,
The command availability check that depends on the input argument can be implemented as a method.
for example
public bool CanExecuteCloseDocument (int blah) => Documents.Any();
public void ExecuteCloseDocument (int blah) { Documents.Remove(Documents.Last()); }
That aside the main issue here is that the view is unaware of the changes to the collection to know to refresh property changes.
Refer to this http://www.postsharp.net/blog/post/Announcing-PostSharp-42-RC
Dependencies to collections
When you add the [AggregateAllChanges] attribute to a field or
automatic property, any change to a property of the object assigned to
this field/property will be interpreted as a change to the
field/property itself. The attribute now works only for collections.
[NotifyPropertyChanged]
public class MyWindowViewModel {
/// Anything bound to this refreshes just fine as expected
[AggregateAllChanges] // <-- when the collection changes to cause notification
public ObservableCollection<SomeType> Documents { get; } = new ObservableCollection<SomeType>();
[Command]
public ICommand AddDocumentCommand { get; set; }
public void ExecuteAddDocument () { Documents.Add(new SomeType()); }
[Command]
public ICommand CloseDocumentCommand { get; set; }
public bool CanExecuteCloseDocument => Documents.Any();
public void ExecuteCloseDocument () { Documents.Remove(Documents.Last()); }
}
With PostSharp LINQ expression (or virtual calls, delegates, external methods) wouldn't work well for CanExecute's.
But expression on properties that implement INotifyPropertyChanged work fantastic (even for nested properties). ObservableCollection implements INotifyPropertyChanged, we don't need LINQ:
public bool CanExecuteCloseDocument => Documents.Count > 0;

Refactoring C# event based with SQL Server operations

I am not sure how to decide about how to refactor some production code. This code works as select records top 1 from db and decided to column containing value under the below.
switch(column_value):
case send_email:
send_email.DoIt();
case enable_somexx:
enable_somexx.DoIt();
case response_email:
response_email.DoIt();
Showing the below examples, there are created classes for every events (records) including a DoIt() method(SendMail, DecideMail, ResponseMail, MailXXX, enable_somexx). The classes include 3 subfolders actions named action, decision, response (actually these classes irrelevant which other because code select top 1 record)
I'm thinking of refactoring this code logic like this:
Create base class named Behaviour
other 3 main classes will inherit from this base class
Code:
public abstract Behaviour
{
public virtual void DoIt(string type) {
}
}
--Also another classes Decision, Response will inherit from Behaviour.
public class Action : Behaviour
{
override void DoIt(string type) {
}
}
public class Email : Action
{
override void DoIt(string type)
{
if(type == SEND)
call_sendmethod
else if(xxx_operation_about_mail)
call_xxx_operation_about_mail
}
}
But I cannot handle (actually I don't like my solution because I don't want to create same class every operations like EmailAction, EmailResponse, EmailDecision or another operations)
If you make this code block refactoring, how would you do it?
Thank you.
Using your idea of refactoring ... this is how I would code it:
Here is an outline:
Create an abstract class for Behavior
Create an action class which inherits Behavior
Then you can code like this to trigger desire "action".
Notice how I override the "Send" behavior to customize it to "special sent".
Here is the fiddle: https://dotnetfiddle.net/m3tjWl
Blockquote
public class Program : Action
{
public static void Main()
{
Console.WriteLine("Hello World");
var command = Console.ReadLine();
//trigger send from Action class
Action x = new Action();
x.DoIt(command);
//trigger send from behavior class
//the lines below are added to show how you can still access the parent behavior, remove or use where appropriate
Behaviour y = x;
y.Send();
}
}
public abstract class Behaviour
{
public virtual void Send()
{
Console.WriteLine("sent");
}
public virtual void EnableX()
{
Console.WriteLine("enabled");
}
public virtual void Reply()
{
Console.WriteLine("replied");
}
public abstract void DoIt(string type);
}
public class Action : Behaviour
{
public override void DoIt(string type)
{
if(type.ToUpper() == "SEND")
this.Send();
else if (type.ToUpper() == "ENABLEX")
this.EnableX();
else if (type.ToUpper() == "REPLY")
this.Reply();
else
Console.WriteLine("Unknown Command");
}
new public void Send()
{
Console.WriteLine("Special Sent");
}
}

specify a object on a public method

I have the following method
public partial class formTabelasPsi : Form
{
private Form1 Opener { get; set; }
public formTabelasPsi(Form1 opener)
{
this.Opener = opener;
InitializeComponent();
}
public static void publicmethod1(string path)
{
//some code related to path
}
}
I want publicmethod1 to check a checkbox whenever this formTabelasPsi runs it.
I tried to specify it using formTabelasPsi.checkBox1.Checked = true; but the code says a object reference is required.
Maybe this is a newbiez question for most of you, but honestly, as a amateur programmer I didn't find this clearly anywhere.
The checkbox belongs to an instance of that form, you need to reference that instance in order to update it
public void publicmethod1(string path)
{
this.checkBox1.Checked = true;
}
The method also needs to belong to an instance of the form, you can find out more about instances here

Save actions or funcs on secondary memory

I am creating a program where the user creates custom commands and execute them when needed. as a result I have a class similar to:
public class Command
{
Action c { get; set; }
// Overloaded Constructors------------------------------------
// changes the volume
public Command(int volumeChange)
{
c = ()=>
SomeClass.ChangeMasterVolume(volumeChange);
}
// Animate something
public Command(int x, int y)
{
c = ()=>
SomeClass.MoveMouse(x,y);
}
// etc.. there are more contructors....
//---------------------------------------------------------
public void ExecuteCommand()
{
c();
}
}
When the user closes the application I will like to save those commands somewhere on disk. There are about 200 different commands and it will be nice if I could serialize an instance from that class. Since it contains an Action it is not possible to serialize it.
It will be nice if I don't have to create a huge switch statement in order to determine what command to execute. What is the best way of dealing with this?
Sounds to me like you simply need to keep an interface around instead of a delegate.
public interface IDoThingy
{
void DoStuff();
}
public class IncreaseVolumeThingy : IDoThingy
{
public int Volume { get; set; }
public IncreaseVolumeThingy(int volume)
{
Volume = volume;
}
public void DoStuff()
{
SomeClass.ChangeMasterVolume(Volume);
}
}
public class Command
{
protected IDoThingy _thingy = null;
public Command(IDoThingy thingy)
{
_thingy = thingy;
}
public void ExecuteCommand()
{
_thingy.DoStuff();
}
}
So instead of creating a set of constructors, you simply make some form of factory based on the command specified. If the user is setting up a Increase volume command, then you new an instance of the IncreaseVolumeThingy and store it. When it is serialized, it can be recreated from state without a delegate.
Use reflection to call a class method by its name. Serialize the class and method name.
http://www.codeproject.com/Articles/19911/Dynamically-Invoke-A-Method-Given-Strings-with-Met

Anonymous inner classes in C#

I'm in the process of writing a C# Wicket implementation in order to deepen my understanding of C# and Wicket. One of the issues we're running into is that Wicket makes heavy use of anonymous inner classes, and C# has no anonymous inner classes.
So, for example, in Wicket, you define a Link like this:
Link link = new Link("id") {
#Override
void onClick() {
setResponsePage(...);
}
};
Since Link is an abstract class, it forces the implementor to implement an onClick method.
However, in C#, since there are no anonymous inner classes, there is no way to do this. As an alternative, you could use events like this:
var link = new Link("id");
link.Click += (sender, eventArgs) => setResponsePage(...);
Of course, there are a couple of drawbacks with this. First of all, there can be multiple Click handlers, which might not be cool. It also does not force the implementor to add a Click handler.
Another option might be to just have a closure property like this:
var link = new Link("id");
link.Click = () => setResponsePage(...);
This solves the problem of having many handlers, but still doesn't force the implementor to add the handler.
So, my question is, how do you emulate something like this in idiomatic C#?
You can make the delegate be part of the constructor of the Link class. This way the user will have to add it.
public class Link
{
public Link(string id, Action handleStuff)
{
...
}
}
Then you create an instance this way:
var link = new Link("id", () => do stuff);
This is what I would do:
Retain Link as an abstract class, use a Factory to instantiate it and pass in your closure / anonymous method as a parameter for the Factory's build method. This way, you can keep your original design with Link as an abstract class, forcing implementation through the factory, and still hiding any concrete trace of Link inside the factory.
Here is some example code:
class Program
{
static void Main(string[] args)
{
Link link = LinkFactory.GetLink("id", () =>
// This would be your onClick method.
{
// SetResponsePage(...);
Console.WriteLine("Clicked");
Console.ReadLine();
});
link.FireOnClick();
}
public static class LinkFactory
{
private class DerivedLink : Link
{
internal DerivedLink(String id, Action action)
{
this.ID = id;
this.OnClick = action;
}
}
public static Link GetLink(String id, Action onClick)
{
return new DerivedLink(id, onClick);
}
}
public abstract class Link
{
public void FireOnClick()
{
OnClick();
}
public String ID
{
get;
set;
}
public Action OnClick
{
get;
set;
}
}
}
EDIT: Actually, This may be a little closer to what you want:
Link link = new Link.Builder
{
OnClick = () =>
{
// SetResponsePage(...);
},
OnFoo = () =>
{
// Foo!
}
}.Build("id");
The beauty is it uses an init block, allowing you to declare as many optional implementations of actions within the Link class as you want.
Here's the relevant Link class (With sealed Builder inner class).
public class Link
{
public sealed class Builder
{
public Action OnClick;
public Action OnFoo;
public Link Build(String ID)
{
Link link = new Link(ID);
link.OnClick = this.OnClick;
link.OnFoo = this.OnFoo;
return link;
}
}
public Action OnClick;
public Action OnFoo;
public String ID
{
get;
set;
}
private Link(String ID)
{
this.ID = ID;
}
}
This is close to what you're looking for, but I think we can take it a step further with optional named arguments, a C# 4.0 feature. Let's look at the example declaration of Link with optional named arguments:
Link link = Link.Builder.Build("id",
OnClick: () =>
{
// SetResponsePage(...);
Console.WriteLine("Click!");
},
OnFoo: () =>
{
Console.WriteLine("Foo!");
Console.ReadLine();
}
);
Why is this cool? Let's look at the new Link class:
public class Link
{
public static class Builder
{
private static Action DefaultAction = () => Console.WriteLine("Action not set.");
public static Link Build(String ID, Action OnClick = null, Action OnFoo = null, Action OnBar = null)
{
return new Link(ID, OnClick == null ? DefaultAction : OnClick, OnFoo == null ? DefaultAction : OnFoo, OnBar == null ? DefaultAction : OnBar);
}
}
public Action OnClick;
public Action OnFoo;
public Action OnBar;
public String ID
{
get;
set;
}
private Link(String ID, Action Click, Action Foo, Action Bar)
{
this.ID = ID;
this.OnClick = Click;
this.OnFoo = Foo;
this.OnBar = Bar;
}
}
Inside the static class Builder, there is a factory method Build that takes in 1 required parameter (The ID) and 3 optional parameters, OnClick, OnFoo and OnBar. If they are not assigned, the factory method gives them a default implementation.
So in your constructor's parameter arguments for Link, you are only required to implement the methods that you need, otherwise they will use the default action, which could be nothing.
The drawback, however, is in the final example, the Link class is not abstract. But it cannot be instantiated outside of the scope of the Link class, because its constructor is private (Forcing the usage of the Builder class to instantiate Link).
You could also move the optional parameters into Link's constructor directly, avoiding the need for a factory altogether.
I started this before #meatthew's good answer - I would do almost exactly the same except - except that I would start with an abstract base class - so that if you did not want to go the route of an anonymous implementation you would be free to do that too.
public abstract class LinkBase
{
public abstract string Name { get; }
protected abstract void OnClick(object sender, EventArgs eventArgs);
//...
}
public class Link : LinkBase
{
public Link(string name, Action<object, EventArgs> onClick)
{
_name = Name;
_onClick = onClick;
}
public override string Name
{
get { return _name; }
}
protected override void OnClick(object sender, EventArgs eventArgs)
{
if (_onClick != null)
{
_onClick(sender, eventArgs);
}
}
private readonly string _name;
private readonly Action<object, EventArgs> _onClick;
}

Categories