公司需要我做 Silver Light rearch
发现silver light 数据绑定多少有点痛苦 object datasource 要等到 vs2010
于是自己写了一个
用得到的自然会看懂 哼哼
Code
Public Enum rowStatus
UnChanged = 0
Inserted = 1
Updated = 2
Deleted = 3
End Enum
Public Class DataTableFake(Of T As ComponentModel.INotifyPropertyChanged)
Implements Collections.Generic.IList(Of T)
Implements System.ComponentModel.INotifyPropertyChanged
Implements System.Collections.Specialized.INotifyCollectionChanged
Private CoreDictionary As New Collections.Generic.Dictionary(Of T, rowStatus)
Private CoreList As New Collections.Generic.List(Of T)
Public Property ItemStatus(ByVal item As T) As rowStatus
Get
If CoreDictionary.ContainsKey(item) Then
Return CoreDictionary(item)
Else
Return Nothing
End If
End Get
Set(ByVal value As rowStatus)
CoreDictionary.Item(item) = value
If value = rowStatus.Deleted Then
RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("VisibleItems"))
End If
End Set
End Property
Public Sub Add(ByVal item As T) Implements System.Collections.Generic.ICollection(Of T).Add
CoreDictionary.Item(item) = rowStatus.UnChanged
CoreList.Add(item)
AddHandler item.PropertyChanged, AddressOf Row_PropertyChanged
RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Add, True, CoreList.IndexOf(item)))
End Sub
Public Sub AddNewRow(ByVal item As T)
CoreDictionary.Item(item) = rowStatus.Inserted
CoreList.Add(item)
RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Add, True, CoreList.IndexOf(item)))
End Sub
Public Sub Clear() Implements System.Collections.Generic.ICollection(Of T).Clear
CoreDictionary.Clear()
CoreList.Clear()
RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Reset))
End Sub
Public Function Contains(ByVal item As T) As Boolean Implements System.Collections.Generic.ICollection(Of T).Contains
Return CoreList.Contains(item)
End Function
Public Sub CopyTo(ByVal array() As T, ByVal arrayIndex As Integer) Implements System.Collections.Generic.ICollection(Of T).CopyTo
CoreList.CopyTo(array, arrayIndex)
End Sub
Public ReadOnly Property Count() As Integer Implements System.Collections.Generic.ICollection(Of T).Count
Get
Return CoreList.Count
End Get
End Property
Public ReadOnly Property IsReadOnly() As Boolean Implements System.Collections.Generic.ICollection(Of T).IsReadOnly
Get
Return False
End Get
End Property
Public Function Remove(ByVal item As T) As Boolean Implements System.Collections.Generic.ICollection(Of T).Remove
CoreDictionary.Remove(item)
Dim res As Boolean = CoreList.Remove(item)
RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Remove, item, CoreList.IndexOf(item)))
Return res
End Function
Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
Return CoreList.GetEnumerator
End Function
Public Event CollectionChanged(ByVal sender As Object, ByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs) Implements System.Collections.Specialized.INotifyCollectionChanged.CollectionChanged
Public Overloads Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
Return CoreList.GetEnumerator
End Function
Public Function IndexOf(ByVal item As T) As Integer Implements System.Collections.Generic.IList(Of T).IndexOf
Return CoreList.IndexOf(item)
End Function
Public Sub Insert(ByVal index As Integer, ByVal item As T) Implements System.Collections.Generic.IList(Of T).Insert
CoreDictionary.Item(item) = rowStatus.Inserted
CoreList.Insert(index, item)
RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Add, True, CoreList.IndexOf(item)))
End Sub
Default Public Property Item(ByVal index As Integer) As T Implements System.Collections.Generic.IList(Of T).Item
Get
Return CoreList(index)
End Get
Set(ByVal value As T)
Dim oobj = CoreList.Item(index)
CoreList.Item(index) = value
CoreDictionary(value) = CoreDictionary(oobj)
CoreDictionary.Remove(oobj)
AddHandler value.PropertyChanged, AddressOf Row_PropertyChanged
RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Replace, value, oobj, index))
End Set
End Property
Public Sub RemoveAt(ByVal index As Integer) Implements System.Collections.Generic.IList(Of T).RemoveAt
Dim obj As T = CoreList(index)
CoreDictionary.Remove(CoreList(index))
CoreList.RemoveAt(index)
RaiseEvent CollectionChanged(Me, New System.Collections.Specialized.NotifyCollectionChangedEventArgs(Collections.Specialized.NotifyCollectionChangedAction.Remove, obj, index))
End Sub
Private Sub Row_PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs)
If CoreDictionary(sender) = rowStatus.UnChanged Then CoreDictionary(sender) = rowStatus.Updated
End Sub
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Private Sub DataTableFake_CollectionChanged(ByVal sender As Object, ByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs) Handles Me.CollectionChanged
RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("VisibleItems"))
End Sub
ReadOnly Property VisibleItems() As T()
Get
Dim q = (From r In Me.CoreList Where CoreDictionary(r) <> rowStatus.Deleted)
Return q.ToArray()
End Get
End Property
End Class
页面代码
Code
Partial Public Class Page
Inherits UserControl
WithEvents ws As New ServiceReferenceDAL.DataAccessWebServiceSoapClient
Public Rows As New DataTableFake(Of ServiceReferenceDAL.BBS)
Public Sub New()
InitializeComponent()
Me.DataGridMain.DataContext = Rows
ws.Get_BBSAsync()
End Sub
Private Sub btnAddNew_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnAddNew.Click
Dim r As New ServiceReferenceDAL.BBS With { _
.Sender = tbUserName.Text, _
.Title = tbTitle.Text, _
.Content = tbContent.Text, _
.Time = Now}
Me.Rows.AddNewRow(r)
End Sub
Private Sub ws_Get_BBSCompleted(ByVal sender As Object, ByVal e As ServiceReferenceDAL.Get_BBSCompletedEventArgs) Handles ws.Get_BBSCompleted
Rows.Clear()
e.Result.ToList.ForEach(AddressOf Rows.Add)
End Sub
Private Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnSubmit.Click
Dim dq = From row In Rows Where Rows.ItemStatus(row) = rowStatus.Deleted Select row
Dim uq = From row In Rows Where Rows.ItemStatus(row) = rowStatus.Updated Select row
Dim iq = From row In Rows Where Rows.ItemStatus(row) = rowStatus.Inserted Select row
Dim param As New ServiceReferenceDAL.struSync With {.DeleteRows = dq.ToArray, .InsertRows = iq.ToArray, .UpdateRows = uq.ToArray}
ws.Sync_BBSAsync(param, param)
End Sub
Private Sub ws_Sync_BBSCompleted(ByVal sender As Object, ByVal e As ServiceReferenceDAL.Sync_BBSCompletedEventArgs) Handles ws.Sync_BBSCompleted
Dim param As ServiceReferenceDAL.struSync = e.UserState
'delete
param.DeleteRows.ToList.ForEach(AddressOf Rows.Remove)
'update
Dim q = (From r In param.UpdateRows From nr In e.Result.UpdateRows Where r.KeyEquals(nr) Select SyncItemReplace(r, nr))
'param.UpdateRows.ToList.ForEach(AddressOf Rows.Remove)
'e.Result.UpdateRows.ToList.ForEach(AddressOf Rows.Add)
'insert
param.InsertRows.ToList.ForEach(AddressOf Rows.Remove)
e.Result.InsertRows.ToList.ForEach(AddressOf Rows.Add)
End Sub
Public Function SyncItemReplace(ByVal olditem As ServiceReferenceDAL.BBS, ByVal newItem As ServiceReferenceDAL.BBS) As Boolean
Rows(Rows.IndexOf(olditem)) = newItem
Rows.ItemStatus(newItem) = rowStatus.UnChanged
End Function
Private Sub btnDelete_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnDelete.Click
If Me.DataGridMain.SelectedIndex <> -1 Then
For Each r As ServiceReferenceDAL.BBS In (From x In Me.DataGridMain.SelectedItems).ToArray
If r.EntityKey Is Nothing Then
Rows.Remove(r)
Else
Rows.ItemStatus(r) = rowStatus.Deleted
End If
Next
End If
End Sub
End Class
Web Service
Code
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Data
' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
' <System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class DataAccessWebService
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function HelloWorld() As String
Return "Hello World"
End Function
<WebMethod()> _
Public Function Get_BBS() As DataAccess.BBS()
Using DContext As New DataAccess.NorthwindEntities
Dim q = From r In DContext.BBS Select r
Return q.ToArray()
End Using
End Function
Public Function Update_BBS(ByVal rows As DataAccess.BBS()) As DataAccess.BBS()
Using DContext As New DataAccess.NorthwindEntities
Dim list As New List(Of DataAccess.BBS)
For Each row As DataAccess.BBS In rows
Dim orow As DataAccess.BBS = Nothing
If DContext.TryGetObjectByKey(row.EntityKey, orow) Then
With orow
.Content = row.Content
.Time = row.Time
.Title = row.Title
.Sender = row.Sender
End With
list.Add(orow)
End If
Next
DContext.SaveChanges()
Return list.ToArray
End Using
End Function
Public Function Insert_BBS(ByVal rows As DataAccess.BBS()) As DataAccess.BBS()
Using DContext As New DataAccess.NorthwindEntities
Array.ForEach(Of DataAccess.BBS)(rows, AddressOf DContext.AddToBBS)
DContext.SaveChanges()
Return rows
End Using
End Function
Public Sub Remove_BBS(ByVal rows As DataAccess.BBS())
Using DContext As New DataAccess.NorthwindEntities
Dim list As New List(Of DataAccess.BBS)
For Each row As DataAccess.BBS In rows
Dim orow As DataAccess.BBS = Nothing
If DContext.TryGetObjectByKey(row.EntityKey, orow) Then
DContext.DeleteObject(orow)
End If
Next
DContext.SaveChanges()
End Using
End Sub
<WebMethod()> _
Function Sync_BBS(ByVal rowStruct As struSync) As struSync
Dim r As struSync
Remove_BBS(rowStruct.DeleteRows)
r.DeleteRows = Nothing
r.InsertRows = Insert_BBS(rowStruct.InsertRows)
r.UpdateRows = Update_BBS(rowStruct.UpdateRows)
Return r
End Function
Public Structure struSync
Public UpdateRows As DataAccess.BBS()
Public DeleteRows As DataAccess.BBS()
Public InsertRows As DataAccess.BBS()
End Structure
End Class
转载于:https://www.cnblogs.com/waynebaby/archive/2009/02/27/1399324.html