Tuesday, December 29, 2015

SignalR Implementation in XAML Page

XAML Page:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.AspNet.SignalR.Client;

namespace SignalRDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        HubConnection _connection;
        IHubProxy _hub;

        // Keep track of when fake "drag and drop" mode is enabled.
        private bool isDragging = false;

        // Store the location where the user clicked the control.
        private double clickOffsetX, clickOffsetY;

        private void window_Loaded(object sender, RoutedEventArgs e)
        {
            Start();
        }

        void label_MouseDown(object sender, MouseButtonEventArgs e)
        {
            isDragging = true;
            var position = e.GetPosition(window);

            var label = sender as Label;
            var l = (double)label.GetValue(Canvas.LeftProperty);
            var t = (double)label.GetValue(Canvas.TopProperty);

            clickOffsetX = l - position.X;
            clickOffsetY = t - position.Y;
        }

        void label_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragging == true)
            {
                // The control coordinates are converted into form coordinates
                // by adding the label position offset.
                // The offset where the user clicked in the control is also
                // accounted for. Otherwise, it looks like the top-left corner
                // of the label is attached to the mouse.

                var label = sender as Label;
                var position = e.GetPosition(window);

                var x = position.X + clickOffsetX;
                var y = position.Y + clickOffsetY;

                SetShapePosition(label, x, y);

                _hub.Invoke("MoveShape", int.Parse(label.Name.Replace("shape", "")), x, y);
            }
        }

        void label_MouseUp(object sender, MouseButtonEventArgs e)
        {
            isDragging = false;
        }

        private void Start()
        {
            _connection = new HubConnection("http://localhost/SignalRChat/myhubs/hubs");

            _hub = _connection.CreateHubProxy("SignalRHub");

            _connection.Start().Wait();

            _hub.On<int>("usersConnected", (count) =>
            {
                this.Dispatcher.Invoke(() =>
                    UpdateUserCount(count)
                );
            });

            _hub.On<List<Common.Shape>>("shapeList", (list) =>
            {
                this.Dispatcher.Invoke(() =>
                {
                    canvas.Children.Clear();

                    list.ForEach(q =>
                    {
                        var label = new Label();

                        label.Name = string.Format("shape{0}", q.Id);
                        label.Content = q.Name;
                        label.Height = 100;
                        label.Width = 100;
                        label.Padding = new Thickness(10, 10, 0, 0);
                        label.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString(q.Color));
                        SetShapePosition(label, q.X, q.Y);
                        label.FontSize = 20;

                        label.MouseDown += label_MouseDown;
                        label.MouseMove += label_MouseMove;
                        label.MouseUp += label_MouseUp;

                        canvas.Children.Add(label);
                    });
                });
            });

            _hub.On<Common.Shape>("shapeMoved", (shape) =>
            {
                this.Dispatcher.Invoke(() =>
                    UpdatePosition(shape)
                );
            });

            _hub.Invoke("GetShapeList");
        }

        private void SetShapePosition(Label label, double x, double y)
        {
            if (label != null)
            {
                label.SetValue(Canvas.LeftProperty, x);
                label.SetValue(Canvas.TopProperty, y);
            }
        }

        private void UpdateUserCount(int count)
        {
            lblCount.Content = count;
        }

        private void UpdatePosition(Common.Shape shape)
        {
            var label = UIHelper.FindChild<Label>(Application.Current.MainWindow, string.Format("shape{0}", shape.Id));
            SetShapePosition(label, shape.X, shape.Y);
        }
    }

    public class UIHelper
    {
        /// <summary>
        /// Finds a Child of a given item in the visual tree. 
        /// </summary>
        /// <param name="parent">A direct parent of the queried item.</param>
        /// <typeparam name="T">The type of the queried item.</typeparam>
        /// <param name="childName">x:Name or Name of child. </param>
        /// <returns>The first parent item that matches the submitted type parameter. 
        /// If not matching item can be found, 
        /// a null parent is being returned.</returns>
        public static T FindChild<T>(DependencyObject parent, string childName)
           where T : DependencyObject
        {
            // Confirm parent and childName are valid. 
            if (parent == null) return null;

            T foundChild = null;

            int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < childrenCount; i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                // If the child is not of the request child type child
                T childType = child as T;
                if (childType == null)
                {
                    // recursively drill down the tree
                    foundChild = FindChild<T>(child, childName);

                    // If the child is found, break so we do not overwrite the found child. 
                    if (foundChild != null) break;
                }
                else if (!string.IsNullOrEmpty(childName))
                {
                    var frameworkElement = child as FrameworkElement;
                    // If the child's name is set for search
                    if (frameworkElement != null && frameworkElement.Name == childName)
                    {
                        // if the child's name is of the request name
                        foundChild = (T)child;
                        break;
                    }
                }
                else
                {
                    // child element found.
                    foundChild = (T)child;
                    break;
                }
            }

            return foundChild;
        }
    }

}

SignalR Hub Page :

using Microsoft.AspNet.SignalR;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Common;

namespace SignalRChat
{
    public class SignalRHub : Hub
    {
        public SignalRHub()
        {

        }

        #region Moveable Shape
        public async Task GetShapeList() // this method will be called from the client, when the user drag/move the shape
        {
            await Clients.Caller.shapeList(ShapeHandler.Instance.ShapeList); // this method will send the coord x, y to the other users but the user draging the shape
        }

        public async Task MoveShape(int id, double x, double y) // this method will be called from the client, when the user drag/move the shape
        {
            var shape = ShapeHandler.Instance.GetShape(id, x, y);

            if (shape.X != x || shape.Y != y) await Clients.Caller.shapeMoved(shape);

            await Clients.Others.shapeMoved(shape); // this method will send the coord x, y to the other users but the user draging the shape
        }

        public override Task OnConnected() //override OnConnect, OnReconnected and OnDisconnected to know if a user is connected or disconnected
        {
            ShapeHandler.Instance.ConnectedIds.Add(Context.ConnectionId); //add a connection id to the list
            Clients.All.usersConnected(ShapeHandler.Instance.ConnectedIds.Count()); //this will send to ALL the clients the number of users connected
            return base.OnConnected();
        }

        public override Task OnReconnected()
        {
            ShapeHandler.Instance.ConnectedIds.Add(Context.ConnectionId);
            Clients.All.usersConnected(ShapeHandler.Instance.ConnectedIds.Count());
            return base.OnConnected();
        }

        public override Task OnDisconnected(bool stopCalled)
        {
            ShapeHandler.Instance.ConnectedIds.Remove(Context.ConnectionId);
            Clients.All.usersConnected(ShapeHandler.Instance.ConnectedIds.Count());
            return base.OnDisconnected(stopCalled);
        }
        #endregion
    }
}

2 comments:

novin said...

Thank you, that’s great
Very informative article,
طراحی سایت
طراحی وب سایت
سئو
طراحی سایت شرکتی
طراحی سایت ارزان
طراحی سایت فروشگاهی
طراحی سایت
طراحی وب سایت
سئو
طراحی سایت

Jason Borne said...

We are a third party technical support service. Avast Customer Support is here to help you out with the whole procedure to Download Avast Antivirus online, We not only fix your Avast Support related issues but will guide with how to get started with your new Avast product once it gets installed successfully.We at Avast Tech Support provides service to protect your PC from potential online threats and external attacks like viruses, Trojans, malwares, spywares and phishing scams. And Avast Refund. Call on our Avast Phone Number.

Gmail Customer service is a third party technical support service for Gmail users when they face any technical issue or error in their Gmail account. Our Gmail Customer Support team solves issues like forgot Gmail account password, Gmail configuration or Sync issues, recover deleted emails and many more.

Norton Tech Support is a third party service provider and not in any way associated with Norton or any of its partner companies. At Norton Support we offer support for Norton products and sell subscription based additional warranty on computer and other peripheral devices.