|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionIn this article you will find a very interesting note about the way that you can share any kind of Windows control functionality from the server application to the client application. NoteFor simplicity purpose you will find no complex code in the source code. BackgroundIn the past if you shared a class with the .NET Remoting you would certainly know these notes:
Using the codeSo, the code consists of three projects:
It contains two classes: Shared Class Library/// SharedResourcesHandler Class ///
private static TextBox innerTextBox;
/// <summary>
/// Gets or sets the shared TextBox Control in the RemoteLib.
/// </summary>
public static TextBox InnerTextBox
{
get { return innerTextBox; }
set { innerTextBox = value; }
}
private static MonthCalendar innerMonthCalendar;
/// <summary>
/// Gets or sets the shared innerMonthCalendar Control in the RemoteLib.
/// </summary>
public static MonthCalendar InnerMonthCalendar
{
get { return innerMonthCalendar; }
set { innerMonthCalendar = value; }
}
Any kind of .NET controls could be used Instead of TextBox and MonthCalendar to be shared. In the Indeed the /// <summary>
/// Represents the method that will handle cross thread calls.
/// </summary>
/// <param name="text"></param>
private delegate void UIThreadHandler<T>(T param);
/// <summary>
/// Initializes a new instance of the RemotableClass
/// </summary>
public RemotableClass()
{
}
/// <summary>
/// Obtains a lifetime service object to control the lifetime policy for
/// this instance.
/// </summary>
/// <returns>
/// An object of type System.Runtime.Remoting.Lifetime.ILease used to
/// control the lifetime policy for this instance. This is the current
/// lifetime service object for this instance if one exists; otherwise, a
/// new lifetime service object initialized to the value of the
/// System.Runtime.Remoting.Lifetime.LifetimeServices.LeaseManagerPollTime
/// property.
/// </returns>
public override object InitializeLifetimeService()
{
ILease lease = (ILease)base.InitializeLifetimeService();
if (lease.CurrentState == LeaseState.Initial)
{
lease.InitialLeaseTime = TimeSpan.FromMinutes(10);
}
return lease;
}
/// <summary>
/// Writes specified text to the TextBox Control.
/// </summary>
/// <param name="text"></param>
public void WriteText(string text)
{
if (SharedResourcesHandler.InnerTextBox != null)
{
UIThreadHandler<string> uiThreadHandler =
new UIThreadHandler<string>(AsyncWriteText);
if (SharedResourcesHandler.InnerTextBox.InvokeRequired)
SharedResourcesHandler.InnerTextBox.BeginInvoke(uiThreadHandler,
text);
else
SharedResourcesHandler.InnerTextBox.Text = text;
}
}
/// <summary>
/// Writes specified text to the TextBox Control in the UI thread.
/// </summary>
/// <param name="text"></param>
private void AsyncWriteText(string text)
{
SharedResourcesHandler.InnerTextBox.Text = text;
}
/// <summary>
/// Changes the MonthCalendar date to specified date.
/// </summary>
/// <param name="text"></param>
public void ChangeDate(DateTime date)
{
if (SharedResourcesHandler.InnerMonthCalendar != null)
{
UIThreadHandler<DateTime> uiThreadHandler =
new UIThreadHandler<DateTime>(AsyncChangeDate);
if (SharedResourcesHandler.InnerMonthCalendar.InvokeRequired)
SharedResourcesHandler.InnerMonthCalendar.BeginInvoke(
uiThreadHandler, date);
else
SharedResourcesHandler.InnerMonthCalendar.SetDate(date);
}
}
/// <summary>
/// Changes the MonthCalendar date to specified date in the UI thread.
/// </summary>
/// <param name="text"></param>
private void AsyncChangeDate(DateTime date)
{
SharedResourcesHandler.InnerMonthCalendar.SetDate(date);
}
Changing properties of shared controls must be a cross thread call, and done with a middle generic delegate named Server ApplicationSo where is the control when you are filling static members of the The answer is one line per control in the server application like this: //Assigning Control from UI to static member of SharedResourcesHandler class
SharedResourcesHandler.InnerTextBox = this.txtRemote;
SharedResourcesHandler.InnerMonthCalendar = this.mcRemote;
Remaining server code is for Registering RemotableClass for enabling remote access TcpServerChannel channel = new TcpServerChannel(8080);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.ApplicationName = "RemotableClass";
RemotingConfiguration.RegisterWellKnownServiceType(typeof(
RemoteLib.RemotableClass), "RemotableClass",
WellKnownObjectMode.SingleCall);
Also you can use the Remoting section in the server configuration instead of preceding code. Client ApplicationIn the client application the first step is getting remote object with this: TcpChannel channel = new TcpChannel();
ChannelServices.RegisterChannel(channel,false);
rClass = (RemotableClass)Activator.GetObject(typeof(RemotableClass),
"tcp://127.0.0.1:8080/RemotableClass");
I used localhost for testing purpose you can use any valid IP Addresses instead. Also you can use configuration file to configure remoting enabled application. Second step is calling shared object wrapper methods with events in the client application. /// <summary>
/// Calling WriteText method of RemotableClass
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtRemote_TextChanged(object sender, EventArgs e)
{
rClass.WriteText(txtRemote.Text);
}
/// <summary>
/// Calling ChangeDate method of RemotableClass
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void mcRemote_DateChanged(object sender, DateRangeEventArgs e)
{
rClass.ChangeDate(mcRemote.SelectionStart);
}
This is a test application, in your real application you must use this trick object oriented.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||