Imports System.Net
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Shapes
Imports C1.Silverlight
Imports C1.Silverlight.FlexGrid

Namespace DragCells
	Partial Public Class MainPage
		Inherits UserControl
		Public Sub New()
			InitializeComponent()

			' ensure flex template has been loaded
			_flex.ApplyTemplate()

			' make rows tall enough to show our custom objects
			_flex.Rows.DefaultSize = 50

			' no editing
			_flex.IsReadOnly = True

			' create unbound rows and columns
			For r As Integer = 0 To 49
				_flex.Rows.Add(New Row())
			Next r
			For c As Integer = 0 To 9
				_flex.Columns.Add(New Column())
			Next c

			' create objects (model) and assign them to grid cells
			For r As Integer = 0 To _flex.Rows.Count - 1
				For c As Integer = 0 To _flex.Columns.Count - 1
					If (r + c) Mod 2 = 0 Then
						_flex(r, c) = New MyDataObject(r, c)
					End If
				Next c
			Next r

			' register flex as drop target
			Dim ddMgr = New C1DragDropManager()
			ddMgr.RegisterDropTarget(_flex, True)
			AddHandler ddMgr.DragDrop, AddressOf _ddMgr_DragDrop

			' activate custom cell factory
			_flex.CellFactory = New MyCellFactory(ddMgr)
		End Sub

		' handle user dragging a cell to a new position
		Private Sub _ddMgr_DragDrop(ByVal source As Object, ByVal e As DragDropEventArgs)
			' get view object being dragged
			Dim bdr = TryCast(e.DragSource, Border)
			Dim viewObject = TryCast(bdr.Child, MyViewObject)
			If viewObject IsNot Nothing Then
				' get target cell
				Dim ht = _flex.HitTest(e.GetPosition(_flex))
				If ht.CellType = CellType.Cell AndAlso ht.Row > -1 AndAlso ht.Column > -1 Then
					' move object to target cell 
					Dim oldRange = New CellRange(bdr)
					_flex(oldRange.Row, oldRange.Column) = Nothing
					_flex(ht.Row, ht.Column) = viewObject.DataObject

					' and move the selection
					_flex.Select(ht.Row, ht.Column)
				End If
			End If
		End Sub
	End Class

	''' <summary>
	''' Some POCO object. This is the model.
	''' </summary>
	Public Class MyDataObject
		Public Sub New(ByVal r As Integer, ByVal c As Integer)
			Name = String.Format("cell {0},{1}", r, c)
			Temperature = (r + c) * 20
		End Sub
		Private privateName As String
		Public Property Name() As String
			Get
				Return privateName
			End Get
			Set(ByVal value As String)
				privateName = value
			End Set
		End Property
		Private privateTemperature As Integer
		Public Property Temperature() As Integer
			Get
				Return privateTemperature
			End Get
			Set(ByVal value As Integer)
				privateTemperature = value
			End Set
		End Property
	End Class

	''' <summary>
	''' Framework element that represents a cell. This is the view.
	''' Each cell is bound to a MyDataObject in the view.
	''' </summary>
	Public Class MyViewObject
		Inherits StackPanel
		Private _flex As C1FlexGrid

		Public Sub New(ByVal flex As C1FlexGrid, ByVal data As MyDataObject)
			_flex = flex
			DataObject = data

			Orientation = System.Windows.Controls.Orientation.Vertical

			Dim tb1 = New TextBlock()
			tb1.Text = data.Name
			tb1.HorizontalAlignment = HorizontalAlignment.Center
			tb1.FontSize = 12
			Children.Add(tb1)

			Dim tb2 = New TextBlock()
			tb2.Text = data.Temperature.ToString()
			tb2.HorizontalAlignment = HorizontalAlignment.Center
			tb2.FontSize = 8
			Children.Add(tb2)
		End Sub
		Private privateDataObject As MyDataObject
		Public Property DataObject() As MyDataObject
			Get
				Return privateDataObject
			End Get
			Set(ByVal value As MyDataObject)
				privateDataObject = value
			End Set
		End Property
	End Class

	''' <summary>
	''' Cell factory used to create the MyElement view objects (cells, vistualized) that 
	''' correspond to the MyDataObject model objects (actual data, permanent).
	''' </summary>
	Public Class MyCellFactory
		Inherits CellFactory
		Private _ddMgr As C1DragDropManager

		Public Sub New(ByVal ddMgr As C1DragDropManager)
			_ddMgr = ddMgr
		End Sub
		Public Overrides Sub CreateCellContent(ByVal grid As C1FlexGrid, ByVal bdr As Border, ByVal range As CellRange)
			' get the data object stored in the unbound grid
			Dim obj = TryCast(grid(range.Row, range.Column), MyDataObject)
			If obj IsNot Nothing Then
				' create a custom view object
				Dim e = New MyViewObject(grid, obj)

				' assign it to the cell
				bdr.Child = e

				' register cell border as a drag source
				_ddMgr.RegisterDragSource(bdr, DragDropEffect.Move, ModifierKeys.None)
			Else
				MyBase.CreateCellContent(grid, bdr, range)
			End If
		End Sub
		Public Overrides Sub DisposeCell(ByVal grid As C1FlexGrid, ByVal cellType_Renamed As CellType, ByVal cell As FrameworkElement)
			_ddMgr.RegisterDragSource(cell, DragDropEffect.None, ModifierKeys.None)
			MyBase.DisposeCell(grid, cellType_Renamed, cell)
		End Sub
	End Class
End Namespace
