Click here to Skip to main content
15,886,720 members
Articles / Programming Languages / C#

Silver Draw - A Silverlight Based Collaboration White Board with Drawing and Chat

Rate me:
Please Sign up or sign in to vote.
4.98/5 (37 votes)
2 Nov 2009CPOL9 min read 139.5K   3.1K   137  
Silver Draw shows how to use Silverlight and WCF Polling Duplex services to create realtime collaboration apps.
  • silverdraw.zip
    • Client
      • .svn
        • all-wcprops
        • entries
        • format
        • prop-base
        • props
        • text-base
          • App.xaml.cs.svn-base
          • App.xaml.svn-base
          • Page.xaml.cs.svn-base
          • Page.xaml.svn-base
          • ScreenObject.cs.svn-base
          • ServiceReferences.ClientConfig.svn-base
          • Silverdraw.Client.csproj.svn-base
          • Silverdraw.Client.csproj.user.svn-base
        • tmp
          • prop-base
          • props
          • text-base
      • App.xaml
      • App.xaml.cs
      • Bin
        • .svn
          • all-wcprops
          • entries
          • format
          • prop-base
          • props
          • text-base
          • tmp
            • prop-base
            • props
            • text-base
        • Debug
          • .svn
            • all-wcprops
            • entries
            • format
            • prop-base
              • SilverPaintGadget.dll.svn-base
              • SilverPaintGadget.pdb.svn-base
              • SilverPaintGadget.xap.svn-base
              • System.Json.dll.svn-base
              • System.Runtime.Serialization.Json.dll.svn-base
              • System.ServiceModel.PollingDuplex.dll.svn-base
            • props
            • text-base
              • AppManifest.xaml.svn-base
              • SilverPaintGadget.dll.svn-base
              • SilverPaintGadget.pdb.svn-base
              • SilverPaintGadget.xap.svn-base
              • System.Json.dll.svn-base
              • System.Json.xml.svn-base
              • System.Runtime.Serialization.Json.dll.svn-base
              • System.Runtime.Serialization.Json.xml.svn-base
              • System.ServiceModel.PollingDuplex.dll.svn-base
              • System.ServiceModel.PollingDuplex.xml.svn-base
              • TestPage.html.svn-base
            • tmp
              • prop-base
              • props
              • text-base
          • AppManifest.xaml
          • de
            • .svn
              • all-wcprops
              • entries
              • format
              • prop-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • props
              • text-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • tmp
                • prop-base
                • props
                • text-base
            • System.Json.resources.dll
            • System.Runtime.Serialization.Json.resources.dll
            • System.ServiceModel.PollingDuplex.resources.dll
            • System.Windows.Controls.resources.dll
          • es
            • .svn
              • all-wcprops
              • entries
              • format
              • prop-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • props
              • text-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • tmp
                • prop-base
                • props
                • text-base
            • System.Json.resources.dll
            • System.Runtime.Serialization.Json.resources.dll
            • System.ServiceModel.PollingDuplex.resources.dll
            • System.Windows.Controls.resources.dll
          • fr
            • .svn
              • all-wcprops
              • entries
              • format
              • prop-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • props
              • text-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • tmp
                • prop-base
                • props
                • text-base
            • System.Json.resources.dll
            • System.Runtime.Serialization.Json.resources.dll
            • System.ServiceModel.PollingDuplex.resources.dll
            • System.Windows.Controls.resources.dll
          • it
            • .svn
              • all-wcprops
              • entries
              • format
              • prop-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • props
              • text-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • tmp
                • prop-base
                • props
                • text-base
            • System.Json.resources.dll
            • System.Runtime.Serialization.Json.resources.dll
            • System.ServiceModel.PollingDuplex.resources.dll
            • System.Windows.Controls.resources.dll
          • ja
            • .svn
              • all-wcprops
              • entries
              • format
              • prop-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • props
              • text-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • tmp
                • prop-base
                • props
                • text-base
            • System.Json.resources.dll
            • System.Runtime.Serialization.Json.resources.dll
            • System.ServiceModel.PollingDuplex.resources.dll
            • System.Windows.Controls.resources.dll
          • ko
            • .svn
              • all-wcprops
              • entries
              • format
              • prop-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • props
              • text-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • tmp
                • prop-base
                • props
                • text-base
            • System.Json.resources.dll
            • System.Runtime.Serialization.Json.resources.dll
            • System.ServiceModel.PollingDuplex.resources.dll
            • System.Windows.Controls.resources.dll
          • Silverdraw.Client.dll
          • SilverPaintGadget.dll
          • SilverPaintGadget.xap
          • System.Json.dll
          • System.Json.xml
          • System.Runtime.Serialization.Json.dll
          • System.Runtime.Serialization.Json.xml
          • System.ServiceModel.PollingDuplex.dll
          • System.ServiceModel.PollingDuplex.xml
          • System.Windows.Controls.dll
          • System.Windows.Controls.xml
          • TestPage.html
          • zh-Hans
            • .svn
              • all-wcprops
              • entries
              • format
              • prop-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • props
              • text-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • tmp
                • prop-base
                • props
                • text-base
            • System.Json.resources.dll
            • System.Runtime.Serialization.Json.resources.dll
            • System.ServiceModel.PollingDuplex.resources.dll
            • System.Windows.Controls.resources.dll
          • zh-Hant
            • .svn
              • all-wcprops
              • entries
              • format
              • prop-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • props
              • text-base
                • System.Json.resources.dll.svn-base
                • System.Runtime.Serialization.Json.resources.dll.svn-base
                • System.ServiceModel.PollingDuplex.resources.dll.svn-base
              • tmp
                • prop-base
                • props
                • text-base
            • System.Json.resources.dll
            • System.Runtime.Serialization.Json.resources.dll
            • System.ServiceModel.PollingDuplex.resources.dll
            • System.Windows.Controls.resources.dll
      • ColorPicker
        • .svn
          • all-wcprops
          • entries
          • format
          • prop-base
          • props
          • text-base
            • ColorPicker.xaml.cs.svn-base
            • ColorPicker.xaml.svn-base
          • tmp
            • prop-base
            • props
            • text-base
        • ColorPicker.xaml
        • ColorPicker.xaml.cs
      • Helpers
      • Page.xaml
      • Page.xaml.cs
      • Properties
        • .svn
          • all-wcprops
          • entries
          • format
          • prop-base
          • props
          • text-base
            • AppManifest.xml.svn-base
            • AssemblyInfo.cs.svn-base
          • tmp
            • prop-base
            • props
            • text-base
        • AppManifest.xml
        • AssemblyInfo.cs
      • Resources
        • .svn
          • all-wcprops
          • entries
          • format
          • prop-base
            • brush.jpg.svn-base
            • circle.PNG.svn-base
            • pen.jpg.svn-base
            • pencil.jpg.svn-base
            • rect.PNG.svn-base
            • sticky.jpg.svn-base
          • props
          • text-base
            • brush.jpg.svn-base
            • circle.PNG.svn-base
            • pen.jpg.svn-base
            • pencil.jpg.svn-base
            • rect.PNG.svn-base
            • sticky.jpg.svn-base
          • tmp
            • prop-base
            • props
            • text-base
        • brush.jpg
        • circle.PNG
        • pen.jpg
        • pencil.jpg
        • rect.PNG
        • sticky.jpg
      • ScreenObject.cs
      • Service References
        • .svn
          • all-wcprops
          • entries
          • format
          • prop-base
          • props
          • text-base
          • tmp
            • prop-base
            • props
            • text-base
        • Proxy
          • .svn
            • all-wcprops
            • entries
            • format
            • prop-base
            • props
            • text-base
              • configuration.svcinfo.svn-base
              • configuration91.svcinfo.svn-base
              • DuplexDrawService.disco.svn-base
              • DuplexDrawService.wsdl.svn-base
              • DuplexDrawService.xsd.svn-base
              • DuplexDrawService1.xsd.svn-base
              • DuplexDrawService2.xsd.svn-base
              • Reference.cs.svn-base
              • Reference.svcmap.svn-base
            • tmp
              • prop-base
              • props
              • text-base
          • configuration.svcinfo
          • configuration91.svcinfo
          • DuplexDrawService.disco
          • DuplexDrawService.wsdl
          • DuplexDrawService.xsd
          • DuplexDrawService1.xsd
          • DuplexDrawService2.xsd
          • Reference.cs
          • Reference.svcmap
      • ServiceReferences.ClientConfig
      • Silverdraw.Client.csproj
      • Silverdraw.Client.csproj.user
    • Server
      • .svn
        • all-wcprops
        • dir-prop-base
        • entries
        • format
        • prop-base
        • props
        • text-base
          • ClientAccessPolicy.xml.svn-base
          • DrawData.cs.svn-base
          • DuplexDrawService.svc.cs.svn-base
          • DuplexDrawService.svc.svn-base
          • IDuplexDrawCallback.cs.svn-base
          • IDuplexDrawService.cs.svn-base
          • Silverdraw.html.svn-base
          • Silverdraw.Publish.xml.svn-base
          • Silverdraw.Server.csproj.svn-base
          • Silverdraw.Server.csproj.user.svn-base
          • Silverlight.js.svn-base
          • Web.config.svn-base
          • Web.Debug.config.svn-base
          • Web.Release.config.svn-base
        • tmp
          • prop-base
          • props
          • text-base
      • App_Data
        • .svn
          • all-wcprops
          • entries
          • format
          • prop-base
          • props
          • text-base
          • tmp
            • prop-base
            • props
            • text-base
      • bin
        • Silverdraw.Server.dll
        • System.Data.DataSetExtensions.dll
        • System.ServiceModel.PollingDuplex.dll
        • System.Web.Extensions.dll
      • ClientAccessPolicy.xml
      • ClientBin
        • SilverPaintGadget.xap
      • default.htm
      • DrawData.cs
      • DuplexDrawService.svc
      • DuplexDrawService.svc.cs
      • IDuplexDrawCallback.cs
      • IDuplexDrawService.cs
      • Properties
        • .svn
          • all-wcprops
          • entries
          • format
          • prop-base
          • props
          • text-base
            • AssemblyInfo.cs.svn-base
          • tmp
            • prop-base
            • props
            • text-base
        • AssemblyInfo.cs
      • Service References
        • .svn
          • all-wcprops
          • entries
          • format
          • prop-base
          • props
          • text-base
          • tmp
            • prop-base
            • props
            • text-base
      • Silverdraw.Publish.xml
      • Silverdraw.Server.csproj
      • Silverdraw.Server.csproj.user
      • Silverdraw.Server.Publish.xml
      • Silverlight.js
      • Web.config
      • Web.Debug.config
      • Web.Release.config
    • Silverdraw.sln
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Windows.Controls.Primitives;
using System.Windows.Browser;
using System.Windows.Markup;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Globalization;
using System.Text;
using System.Collections.ObjectModel;
using Silverdraw.Server;


namespace Silverdraw.Client
{
    public partial class Page : UserControl
    {

        #region Private

        bool drawing = false;
        DrawingArea drawArea;
        DuplexClientHelper<DrawData> proxy ;
        string userName=string.Empty;
       #endregion

        #region Ctor and Methods

        public Page()
        {
            InitializeComponent();
            drawArea = new DrawingArea(this.DrawingCanvas);
            drawArea.Tool = CurrentTool.Pencil;
            drawArea.StrokeColor = new SolidColorBrush(Colors.Gray);
            drawArea.FillColor = new SolidColorBrush(Colors.Red);
            drawArea.StrokeWidth = 5;
            this.DataContext = drawArea;

            drawArea.DataAdded += (data) =>
                {
                    try
                    {
                        proxy.Client.DrawAsync(data); 
                    }
                    catch { }
                };
        }


         /// <summary>
        /// Initialize the connection
        /// </summary>
        void InitServiceConnection()
        {
            proxy = new DuplexClientHelper<DrawData>();
            string endPointAddress =  "http://"
              + App.Current.Host.Source.DnsSafeHost
              + ":"
              + App.Current.Host.Source.Port.ToString(CultureInfo.InvariantCulture)
              + "/DuplexDrawService.svc";

                //"http://localhost:2632/DuplexDrawService.svc";

            proxy.GotNotification += (operation, data) =>
                {
                    if (data != null)
                    {
                        if (data.Content.StartsWith("@draw:"))
                        {
                            if (data.From != userName)
                            {
                                drawArea.AddObjects(data.Content.Substring("@draw:".Length), data.From);
                                ShowNotification(data.From + " has drawn something");
                            }
                        }
                        else if (data.Content.StartsWith("@added:"))
                        {
                            ShowNotification(data.Content.Substring("@added:".Length) + " Joined");
                        }
                    }
                };

            proxy.GotError += (operation, data) => ShowNotification("Error:" + data.Message);
            proxy.Initialize(endPointAddress);
            proxy.Client.RegisterAsync(this.InputUser.Text);
        }

        /// <summary>
        /// Shows a notification from server
        /// </summary>
        /// <param name="data"></param>
        public void ShowNotification(string data)
        {
            Notification.Text = "Notification: " + data;
        }


        #endregion

        #region Events

        private void ButtonSelect_Click(object sender, RoutedEventArgs e)
        {
            this.ColorPanel.Visibility = Visibility.Collapsed;
        }

        private void ButtonTool_Click(object sender, RoutedEventArgs e)
        {
            var btn=sender as Button;

            if (btn != null && btn.Tag is string)
            {
                drawArea.Tool=(CurrentTool)Enum.Parse(typeof(CurrentTool),btn.Tag as string,true); 
            }
        }

        private void DrawingCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            drawArea.PrevPoint  = e.GetPosition(this.DrawingCanvas);
            drawArea.StartPoint = drawArea.PrevPoint;
            drawArea.TempHolder.Clear();

            if (drawing)
                drawing = false;
            else
            {
                drawing = true;
                var cupt = e.GetPosition(this.DrawingCanvas);
                e.Handled = true;
            }

        }

        private void DrawingCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            drawing = false;
            var cupt = e.GetPosition(this.DrawingCanvas);
            drawArea.HideVirtualLine();

            cupt = drawArea.DrawOnComplete(cupt);

        }

        private void DrawingCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (drawing && drawArea.PrevPoint != null)
            {
                var cupt = e.GetPosition(this.DrawingCanvas);
                cupt = drawArea.DrawOnMove(cupt);
            }

        }

        private void ButtonLogin_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                InitServiceConnection();
                drawArea.MessageCollection.Clear();
                this.DrawingCanvas.Children.Clear();
                this.userName = InputUser.Text;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Unable to connect: " + ex.Message + ". Continuing with out connecting to server!!","Can't Connect",MessageBoxButton.OK);
                UpdateButton.IsEnabled = false;
            }

            this.LayoutRoot.Visibility = Visibility.Visible;
            this.LoginPanel.Visibility = Visibility.Collapsed;
        }
        
        private void UpdateButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var txt = this.TalkText.Text;
                this.TalkText.Text = string.Empty;
                var talk = new ScreenObject() { Text = txt, Type = ScreenObjectType.Text };
                drawArea.MessageCollection.Insert(0, new TalkItem()
                {
                    Text = talk.Text,
                    Time = DateTime.Now.ToShortTimeString(),
                    From = "Me"
                });
                var obj = new ScreenObject[] { talk };
                proxy.Client.DrawAsync(obj.JsonSerialize());
            }
            catch { }
        }

        private void ButtonColor_Click(object sender, MouseButtonEventArgs e)
        {
            if (sender is Canvas)
            {
                this.ColorPanel.Visibility = Visibility.Visible;
                ColorPanel.Tag = sender;
                ColorPicker.ColorChanged += (s, c) =>
                {
                    (ColorPanel.Tag as Canvas).Background = c.newColor;
                };
            }
        }

        private void ButtonVideo_Click(object sender, RoutedEventArgs e)
        {
            HtmlPage.PopupWindow(new Uri(@"http://amazedsaint.blogspot.com/2009/11/silverlight-wcf-duplex-services.html"), "_blank", null); 
        }

        #endregion

       

       
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India
Architect, Developer, Speaker | Wannabe GUT inventor & Data Scientist | Microsoft MVP in C#

Comments and Discussions