Question

I use the following code to Invoke and access properties on my from from a different thread.

    public static void PFA(Action<frmain> action)
    {
        var form = Form.ActiveForm as frmain;
        if (form != null)
        {
            form.PerformAction(action);
        }
    }

    public void PerformAction(Action<frmain> action)
    {
        if (InvokeRequired)
            Invoke(action, this);
        else
            action(this);
    }

My Question:

If I call PFA(form => form.Richbox1.Text = "Test") - I want PFA() to check if the action is (Richbox1.Text) and if so then Add "\n" to the text("Test").

The Idea is to call

PFA(form => form.Richbox1.Text = "Test"); 

instead of

PFA(form => form.Richbox1.Text = "Test\n");

In other words I want to add a new line automaticly if the action is "Richbox1.Text ="

How I do that? I never worked with actions before.

Was it helpful?

Solution

What if you did:

PFA(form => UpdateTextBox(form.Richbox1,"Test"));


public void UpdateTextBox(RichTextBox box,string text)
{

   if (box.Name=="Richbox1")
   {
       text+="\n";
   }

   box.AppendText(text);
}

Your not going to be able to look inside the action and determine it's using a specific cotnrol from outside of the action. So either you need to add the \n before you call PFA, or have PFA call a function which will do what you want, or have PFA implement the logic.

OTHER TIPS

You can add an extension method to do the trick. Try the following.

public static void AddNewLineIfMatch(this RichTextBox rtb, string toMatch) {
  if ( rtb.Text == toMatch ) {
    rtb.AppendText("\n");
  }
}

PFDA(() => form.Richbox1.AddNewLineIfMatch("Test"));

EDIT Used the AppendText method instead of Text+=

You can't do this the way you want. PFA function can not check what's is inside your delegate. Think how you can solve your task another way.

[offtopic]
PS. Also, your naming convention is not very good. "PFA" doesn't explain what the function does and as for "frmain" - usually class names start with capital letter.
[/offtopic]

UPDATE: I would do it a little bit better, than Josh offered:

PFA(form => SetControlText(form.Richbox1, "Test"));

public void SetControlText(Control control, string text)
{ 
  control.Text = text;  
  // choose control type for which you want to add new line
  if(control is RichTextbox || control is TextBox || control is ... )
    control.Text += Environment.NewLine;
}

You could accomplish this by moving from Action to Expression>. Then you can look at what's happening in the method like so

public static void PFA(Expression<Action<frmain>> expression) {
    // this will give you form.RichTextBox1
    var targetFormProperty = (MemberAccessExpression)expression.Body;
    // this only works for your example given. this gives you RichTextBox1.Text
    var textProperty = (MemberAccessExpression)targetFormProperty.Expression;

    // this is how you would run your action like normal
    var action = expression.Compile();
    action(); // invoke action (you would want to wrap this in the invoke check)
}

This gives you the info you need to figure out the property, but not how to append the \n. I'll leave this up to you to find out. I think this is overkill here, but who knows, maybe this could help you or someone else, or even inspire a nice solution.

A nice solution i could possibly think of where you could reuse this functionality is like a rule engine where you might compare what the property being accessed is and run an action right after it, etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top