GroupLab.Networking :: Vector

This example demonstrates how two clients can create and modify a vector using a Shared Dictionary.

Download the source code and executable

 Sections of this example:

  1. Setting up the form
  2. What is a Vector
  3. Adding code
    1. Form1 Properties
    2. Connect
    3. SD Connected Event
    4. Receiving Vector Changes
    5. The Add Button
    6. Selected Index Changed
    7. The Modify Button
    8. The Remove Button
  4. What you will get

I. Setting up the form

1. Start a new C# Windows Application in Visual Studio and add a reference to GroupLab.Networking.dll.  For detailed instructions click here.

2. Add a TextBox, four Buttons and a ListBox to the Form like in the image below


       

The names of the buttons are as follows: button1 is the Connect button, button2 is the Modify button, button3 is the Add button and button4 is the Remove button.

3. Drag a Shared Dictionary and a Subscription from the toolbox to the form. Rename the SharedDictionary1 to SD .


       


II. What is a Vector

A Shared Dictionary can hold values, maps and vector at any path. A vector is a one dimensional array of elements of the same type. You can use the already implemented SharedDictionary.Vector class. The normal rules of using vectors apply, with a little twist though.

Indexing: The SharedDictionary.Vector implements two way indexing. This lets you add elements at the beginning, end or middle of the vector. For example:

SD["/path#+0"] = value; will add the value to index 0 of the vector at "/path"
SD["/path#+1"] = value; will add the value to index 1 of the vector at "/path"
SD["/path#-0"] = value; will add the value to the end of the vector at "/path"
SD["/path#-1"] = value; will add the value in the second last position of the vector at "/path"

You can place a vector into a Shared Dictionary either as a whole

    SD["/path"] = theVector;

or element by element

SD["/path#-0"] = element;

In the latter case, each element is added to the end of the vector (you can see the -0 index)

To access the elements of a vector from the Shared Dictionary, first grab the vector like this:

    SharedDictionary.Vector tempVector = SD["/path"] as SharedDictionary.Vector;

then access each element in the normal fashion:

    Object element = tempVector[2];

 


III. Adding code

1. Form1 Properties: We will need an integer that will save the index of the element the mouse clicked on in the ListBox. We will use this index to modify that element or remove that element from the vector.

Add the following property to the Form1 class:

    private int selectedindex;

and in the Form1() constructor add the following initialization:

    selectedindex = -1;


2. Connect: The button will be used to connect to the shared dictionary. When connecting, a Connect dialog will ask the user for a URL to connect to. 

The URL format is: tcp://<computer name or IP>:<port # / dictionary name>
For example, "tcp://localhost:hello" will connect to a shared dictionary named hello on the the local machine.

An event handler is added, SD_Connected , to notify the application that it has successfully opened a connection with the shared dictionary. 

Add the following code to the button1_Click event:

//Connect button is clicked
private void button1_Click(object sender, System.EventArgs e)
{
     GroupLab.Networking.UrlPrompt a = new GroupLab.Networking.UrlPrompt("tcp://localhost:vector");
     if(a.ShowDialog() == DialogResult.Cancel)
         return;

     this.SD.Url = a.Url;// get the URL from the Connect dialog
     // set the event handler in case the connect succeeds 

     this.SD.Connected +=new EventHandler(SD_Connected);
     this.SD.Open();// open the connection to the given URL
}

3. SD Connected Event: This event will fire when the application connects to the shared dictionary.  Our program will allow two or more instances of itself to share a vector and modify it.

Add the following code to the SD_Connected event:

// event handler for the connection opened event
private void SD_Connected(object sender, EventArgs e)
{
     this.subscription1.BeginInit();
     this.subscription1.Pattern = "/vector";//set the pattern to subscribe to
     this.subscription1.Notified += new SubscriptionEventHandler(subscription1_Notified);
     this.subscription1.EndInit();
     this.button1.Enabled = false;// disable the connect button
}


4. Receiving Vector Changes: When the contents of the vector are modified, we will update the ListBox with the new contents. 

Add the following code to the subscription1_Notified event:

// event handler for vector contents changes
private void subscription1_Notified(object sender, SubscriptionEventArgs e)
{
     this.listBox1.Items.Clear();// clear the list

     // get the vector from the shared dictionary

     SharedDictionary.Vector v = SD["/vector"] as SharedDictionary.Vector;

     // repopulate the list
     for(int i=0; i < v.Count; i++)
         this.listBox1.Items.Add(v[i]);
}


5. The Add Button: If text is written in the TextBox and the Add button is pressed then we will add that text at the back of the vector. 

Add the following code to the button3_Click event:

// the Add button
private void button3_Click(object sender, System.EventArgs e)
{
     if(this.textBox1.Text.Length ==0) // if the element is empty then don't add anything
         return;
     SD["/vector#-0"] = this.textBox1.Text;//add the element at the end of the vector
     this.textBox1.Text = "";
}

6. Selected Index Changed: Whenever the user clicks in the ListBox, the index of that element is saved so it can be used for later editing or removal.

Add the following code to the listBox1_SelectedIndexChanged event:

// method used to intercept when an element is selected in the ListBox
private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
     // place the selected vector element in the text box for editing
     this.textBox1.Text = this.listBox1.SelectedItem.ToString();

     SharedDictionary.Vector v = this.SD["/vector"] as SharedDictionary.Vector;

    // save the index of the selected element for later use
     selectedindex = v.IndexOf(this.textBox1.Text,0);
}

7. The Modify Button: This is were we will use the saved index from step 5 to modify a vector element. If the user has previously selected an element in the ListBox, s/he can now edit it in the TextBox and click Modify. The modified element is placed in the vector at the corresponding location.

Add the following code to the button2_Click event:

// the Modify button
private void button2_Click(object sender, System.EventArgs e)
{
     if(selectedindex < 0)// if there is no selected element do nothing
         return;
   
 
     // otherwise set the TextBox text at the appropriate entry in the dictionary

     this.SD["/vector#+"+selectedindex.ToString()] = this.textBox1.Text;

     selectedindex = -1;// unset the saved index
     this.textBox1.Text = "";// clean the edit box
}

8. The Remove Button: Again we will use the saved index from step 5 to remove a vector element. If the user has previously selected an element in the ListBox, the user can click Remove and the element is deleted.

Add the following code to the button4_Click event:

// the Remove button
private void button4_Click(object sender, System.EventArgs e)
{
     if(selectedindex < 0)//if nothing was selected in the ListBox
         return;// do nothing
  
     SharedDictionary.Vector v = this.SD["/vector"] as SharedDictionary.Vector;
     this.SD["/vector"] = null;

     // place the vector in another vector but omit the element to be deleted
     for(int i=0;i < v.Count;i++)
         if(i!=selectedindex)
             this.SD["/vector#-0"] = v[i];

     selectedindex = -1;
     this.textBox1.Text = "";
}


IV. What you will get

1.Open an instance of the application. Hit "Connect".

       

2. In the Connect Dialog enter a hostname:port or leave the default one and press "Open"

       

3. Open one more instance and connect it to the SAME hostname:port. Now both instances can add and modify elements of a vector.