С#:Как получить присвоенное значение от действия?

StackOverflow https://stackoverflow.com/questions/803331

  •  03-07-2019
  •  | 
  •  

Вопрос

Я использую следующий код для вызова свойств и доступа к ним из другого потока.

    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);
    }

Мой вопрос:

Если я позвоню PFA(form => form.Richbox1.Text = "Test") - Я хочу, чтобы PFA() проверил, является ли действие (Richbox1.Text), и если да, то добавьте « » в текст («Тест»).

Идея состоит в том, чтобы позвонить

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

вместо

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

Другими словами, я хочу автоматически добавлять новую строку, если действие «Richbox1.Text =».

Как мне это сделать?Раньше я никогда не работал с действиями.

Это было полезно?

Решение

Что, если бы вы сделали:

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


public void UpdateTextBox(RichTextBox box,string text)
{

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

   box.AppendText(text);
}

Вы не сможете заглянуть внутрь действия и определить, что оно использует определенный элемент управления снаружи действия.Таким образом, либо вам нужно добавить перед вызовом PFA, либо PFA вызовет функцию, которая будет делать то, что вы хотите, либо PFA реализует логику.

Другие советы

Вы можете добавить метод расширения, чтобы добиться цели.Попробуйте следующее.

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

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

РЕДАКТИРОВАТЬ Использовал метод AppendText вместо Text+=.

Вы не можете сделать это так, как хотите.Функция PFA не может проверить, что находится внутри вашего делегата.Подумайте, как можно решить свою задачу по-другому.

[не по теме]
ПС.Кроме того, ваше соглашение об именах не очень хорошее.«PFA» не объясняет, что делает функция, а что касается «frmain» — обычно имена классов начинаются с заглавной буквы.
[/не по теме]

ОБНОВЛЯТЬ:Я бы сделал это немного лучше, чем предлагал Джош:

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;
}

Этого можно добиться, перейдя от действия к выражению>.Затем вы можете посмотреть, что происходит в этом методе, вот так

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)
}

Это дает вам информацию, необходимую для определения свойства, но не дает информации о том, как добавить .Я оставлю это на ваше усмотрение.Я думаю, что здесь это излишне, но кто знает, может быть, это поможет вам или кому-то еще или даже вдохновит на хорошее решение.

Хорошее решение, о котором я мог бы подумать, где вы могли бы повторно использовать эту функциональность, похоже на механизм правил, в котором вы можете сравнить, что такое свойство, к которому осуществляется доступ, и запустить действие сразу после него и т. д.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top