Feedback

C# - Threadsichere und generische Kommunikation Windows Forms

Veröffentlicht von am 03.02.2009
(1 Bewertungen)
Dieses Snippet
http://dotnet-snippets.de/dns/threadsicheres-zuweisen-von-control-eigenschaften-SID829.aspx
gefiel mir so gut daß ich mich entschloß (auch aus gegebenem Anlass), weitere Invoker für andere Bedürfnisse zu schreiben. Mit meiner Klasse ist es möglich, nicht nur Werte in Control-Properties zu schreiben, sondern auch auszulesen. Ausserdem können Methoden von Controls aufgerufen werden. Ich hoffe, Marcel Spies verzeiht mir daß ich seinen PropertyWriter hier verbaut habe.
using System.Security.Permissions;

[assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")]
namespace Cyrons.Forms
{
   using System.Reflection;
   using System.Windows.Forms;

   /// <summary>
   /// Bietet Funktionen für den threadsicheren Zugriff auf Objekte von Windows Forms Controls.
   /// </summary>
   public class ControlCommunicationsManager
   {
      #region Delegates

      private delegate void MethodCaller<ControlType>(
         ControlType control,
         string methodName,
         params object[] parameters)
         where ControlType : Control;

      private delegate object PropertyValueReaderCallback<ControlType>(
          ControlType control, string propertyName)
          where ControlType : Control;

      private delegate void PropertyValueWriterCallback<ControlType, PropertyType>(
          ControlType control, string propertyName, PropertyType value)
          where ControlType : Control;

      #endregion Delegates
      #region Methods

      /// <summary>
      /// Invokes a control method call.
      /// </summary>
      /// <typeparam name="ControlType">The type of the control.</typeparam>
      /// <param name="control">The control.</param>
      /// <param name="methodName">Name of the method.</param>
      /// <param name="parameters">Parameters array for the method to be called.</param>
      public void InvokeControlMethodCall<ControlType>(
         ControlType control,
         string methodName, params object[] parameters)
         where ControlType : Control
      {
         if(control.InvokeRequired)
         {
            MethodCaller<ControlType> callerDelegate = InvokeControlMethodCall;
            control.Invoke(callerDelegate, new object[] { control, methodName, parameters });
         }
         else
         {
            MethodInfo method = control.GetType().GetMethod(methodName);
            method.Invoke(control, parameters);
         }
      }

      /// <summary>
      /// Invokes reading of a control property.
      /// </summary>
      /// <typeparam name="ControlType">The type of the control.</typeparam>
      /// <param name="control">The control.</param>
      /// <param name="propertyName">Name of the property.</param>
      /// <returns></returns>
      public object InvokeControlPropertyReader<ControlType>(
         ControlType control,
         string propertyName)
         where ControlType : Control
      {
         if(control.InvokeRequired)
         {
            PropertyValueReaderCallback<ControlType> cb = InvokeControlPropertyReader;
            return control.Invoke(cb, new object[] { control, propertyName });
         }
         PropertyInfo property = control.GetType().GetProperty(propertyName);
         return property.GetValue(control, null);
      }

      /// <summary>
      /// Invokes writing to a control property.
      /// </summary>
      /// <typeparam name="ControlType">The type of the control.</typeparam>
      /// <typeparam name="PropertyType">The type of the property.</typeparam>
      /// <param name="control">The control.</param>
      /// <param name="propertyName">Name of the property.</param>
      /// <param name="value">The value.</param>
      public void InvokeControlPropertyWriter<ControlType, PropertyType>(
          ControlType control,
          string propertyName,
          PropertyType value)
          where ControlType : Control
      {
         if(control.InvokeRequired)
         {
            PropertyValueWriterCallback<ControlType, PropertyType> cb = InvokeControlPropertyWriter;
            control.Invoke(cb, new object[] { control, propertyName, value });
         }
         else
         {
            PropertyInfo property = control.GetType().GetProperty(propertyName);
            property.SetValue(control, value, null);
         }
      }

      #endregion
   }
}
Abgelegt unter generics, invoke, thread, control, windows forms.

1 Kommentare zum Snippet

Rainer Hilmer schrieb am 03.02.2009:
Ich hatte in der Beschreibung ein Anwendungsbeispiel eingefügt. Warum es nicht erscheint, weiß der Geier. Dann eben nochmal hier:
namespace ReadControlFromOtherThread
{
using System;
using System.Threading;
using System.Windows.Forms;
using Cyrons.Forms;

public partial class Form1 : Form
{
#region Fields

private ControlCommunicationsManager ctrlComManager;

#endregion
#region Constructors

public Form1()
{
InitializeComponent();
ctrlComManager = new ControlCommunicationsManager();
}

#endregion Constructors
#region Methods

private void Button_Try_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(MyOtherThread);
}

private void MyOtherThread(object stateInfo)
{
ctrlComManager.InvokeControlMethodCall(TextBox_Input, "AppendText", " bla bla");

ctrlComManager.InvokeControlPropertyWriter(
Label_Output,
"Text",
"Textlänge = "
+ (int)ctrlComManager.InvokeControlPropertyReader(TextBox_Input, "TextLength"));

ctrlComManager.InvokeControlMethodCall(TextBox_Input, "ScrollToCaret", null);
}

#endregion Methods
}
}
 

Logge dich ein, um hier zu kommentieren!