基于sliverlight + wcf的web 文字版IM 示例

演示地址: http://task.24city.com/default.html

预览界面:


一、布局
采用Grid布局,5行2列
第一行:为登录/注册信息区
第二行:左列为聊天记录区,右列为"最近联系人,我的好友,当前在线"等常见功能区
第三行:显示当前聊天对象以及"加为好友","从好友列表中删除"二个按钮
第四行: 打字聊天栏
第五行:发送按钮

二、机制
a.采用wcf通讯,silverlight调用wcf得到返回结果和发送聊天内容,wcf与数据库交互----即silverlight以wcf为桥梁来操作数据库
b.聊天记录的刷新采用Timer定时器,每隔5秒通过调用wcf更新
c.在线列表利用website中的Global全局字典来实现,每登录或注销一个用户时,均通过wcf向该字典中插入或删除指定key的"记录"

三、一些小技巧:

a.Ctrl+回车 键发送的实现代码:

private void txtContent_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            ModifierKeys keys = Keyboard.Modifiers;

            if (e.Key == Key.Enter && keys == ModifierKeys.Control)
            {
                btnSend_Click(sender, e);
            }
        }

b.TabControl中加载ListBox并附加滚动条的代码:

ListBox _listBox = new ListBox();
_listBox.ItemsSource = _list;
_listBox.DisplayMemberPath = "Value";
_listBox.MouseLeftButtonUp += new MouseButtonEventHandler(_listBox_MouseLeftButtonUp);
ScrollViewer _viewer = new ScrollViewer();
_viewer.Content = _listBox;
_listBox.BorderThickness = new Thickness(0);
this.tblItemRecently.Content = _viewer;
_viewer.Height = pnlTab.ActualHeight - 38;

即TabItem的Content指定为一个ScrollViewer,而这个ScrollViewer的Content再指定为ListBox,用二层嵌套实现


c.客户端登录Ip的取得

silverlight并不能直接取得IP地址,所以这里用website中的wcf做了中转,xap加载时就先利用wcf取回当前Ip,呵

四、代码
代码有点乱,也相对比较长,关键代码全部折叠贴在下面了:

ContractedBlock.gif ExpandedBlockStart.gif MainPage.Xaml
<UserControl xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"  xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"  x:Class="Talker.MainPage"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d
="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable
="d">
    
<Grid x:Name="LayoutRoot" ShowGridLines="False">
        
<Grid.ColumnDefinitions>
            
<ColumnDefinition Width="*"></ColumnDefinition>
            
<ColumnDefinition Width="250"></ColumnDefinition>
        
</Grid.ColumnDefinitions>

        
<Grid.RowDefinitions>
            
<RowDefinition Height="35"></RowDefinition>
            
<RowDefinition Height="*"></RowDefinition>
            
<RowDefinition Height="35"></RowDefinition>
            
<RowDefinition Height="60"></RowDefinition>
            
<RowDefinition Height="35"></RowDefinition>
        
</Grid.RowDefinitions>

        
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal" Grid.Row="0" Grid.ColumnSpan="2" x:Name="pnlLogin" Visibility="Collapsed">
            
<dataInput:Label Content="用户名:" VerticalAlignment="Center" HorizontalAlignment="Center" ></dataInput:Label>
            
<TextBox Width="100" x:Name="txtLoginName" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBox>
            
<dataInput:Label Content="密 码:" Margin="3,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center" ></dataInput:Label>
            
<PasswordBox Width="100" x:Name="txtPwd" VerticalAlignment="Center" HorizontalAlignment="Center"></PasswordBox>
            
<Button Content="登录" Width="60" Margin="3,0,0,0" x:Name="btnLogin" Click="btnLogin_Click" VerticalAlignment="Center" HorizontalAlignment="Center" ></Button>
            
<Button Content="注册" Width="60" Margin="3,0,0,0" x:Name="btnGoToReg" Click="btnGoToReg_Click" VerticalAlignment="Center" HorizontalAlignment="Center" ></Button>
        
</StackPanel>


        
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal" Grid.Row="0" Grid.ColumnSpan="2" x:Name="pnlReg">
            
<dataInput:Label Content="用户名:" VerticalAlignment="Center" ></dataInput:Label>
            
<TextBox Width="90" x:Name="txtRegName" VerticalAlignment="Center"></TextBox>
            
<dataInput:Label Content="呢称:" Margin="3,0,0,0" VerticalAlignment="Center"></dataInput:Label>
            
<TextBox Width="90" x:Name="txtNickName" VerticalAlignment="Center"></TextBox>
            
<dataInput:Label Content="密 码:" Margin="3,0,0,0" VerticalAlignment="Center" ></dataInput:Label>
            
<PasswordBox Width="60" x:Name="txtRegPwd" VerticalAlignment="Center"></PasswordBox>
            
<dataInput:Label Content="再次输入密码:" Margin="3,0,0,0" VerticalAlignment="Center" ></dataInput:Label>
            
<PasswordBox Width="60" x:Name="txtRegPwd2" VerticalAlignment="Center"></PasswordBox>
            
<Button Content="注册" Width="50" Margin="3,0,0,0" x:Name="btnReg" VerticalAlignment="Center" Click="btnReg_Click"></Button>
            
<Button Content="返回登录" Width="60" Margin="3,0,0,0" x:Name="btnBackToLogin" Click="btnBackToLogin_Click" VerticalAlignment="Center"  ></Button>
        
</StackPanel>

        
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal" Grid.Row="0" Grid.ColumnSpan="2" x:Name="pnlLoginOk" Visibility="Collapsed">
            
<TextBlock x:Name="txtLoginOk" Text="1^yjmyzz@126.com@^菩提树下的杨过" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
            
<Button Content="退出" Margin="3,0,0,0" x:Name="btnLogOut" Width="50" VerticalAlignment="Center" HorizontalAlignment="Center" Click="btnLogOut_Click" ></Button>
        
</StackPanel>

        
<TextBox Grid.Row="1" Grid.Column="0" TextWrapping="Wrap" Text="" IsReadOnly="True" x:Name="txtRecord" VerticalScrollBarVisibility="Auto"></TextBox>

        
<StackPanel Grid.Row="1" Grid.Column="1" x:Name="pnlTab">
            
<controls:TabControl x:Name="tblTitle" Margin="3,0,0,0">
                
<controls:TabItem Header="最近联系人" x:Name="tblItemRecently" MouseLeftButtonUp="tblItemRecently_MouseLeftButtonUp" />
                
<controls:TabItem Header="我的好友" x:Name="tblItemMyFriend" MouseLeftButtonUp="tblItemMyFriend_MouseLeftButtonUp" />
                
<controls:TabItem Header="当前在线" x:Name="tblItemOnline" MouseLeftButtonUp="tblItemOnline_MouseLeftButtonUp" />
            
</controls:TabControl>

        
</StackPanel>

        
<StackPanel Grid.Row="2" Grid.ColumnSpan="2" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3,0,0,0">
            
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">
                
<Run>您正在跟 </Run>
                
<Run Foreground="Red" x:Name="txtTarget"></Run>
                
<Run> 聊天:</Run>
            
</TextBlock>
            
<Button x:Name="btnAddFriend"  Content="加为好友" Width="60" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="3,0,0,0" Click="btnAddFriend_Click" Visibility="Collapsed" />
            
<Button x:Name="btnDeleteFriend"  Content="从好友列表中删除" Width="140" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="3,0,0,0" Click="btnDeleteFriend_Click" Visibility="Collapsed" />
            
<dataInput:Label x:Name="lblId" Visibility="Collapsed" Content=""></dataInput:Label>
        
</StackPanel>



        
<TextBox x:Name="txtContent" Text="" Grid.Row="3" Grid.ColumnSpan="2" KeyDown="txtContent_KeyDown" GotFocus="txtContent_GotFocus"></TextBox>
        
<TextBlock Text="按“Ctrl+回车”发送" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center"></TextBlock>

        
<Button x:Name="btnSend" Grid.Row="4" Grid.Column="1" Content="发送" Width="80" HorizontalAlignment="Right" VerticalAlignment="Center" Click="btnSend_Click" ></Button>
   


    
</Grid>
</UserControl>

 

ContractedBlock.gif ExpandedBlockStart.gif MainPage.Xaml.cs
using System;
using System.Collections.Generic;
using System.Json;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using Talker.BLL;
using Talker.Entity;

namespace Talker
ExpandedBlockStart.gifContractedBlock.gif
{
    
public partial class MainPage : UserControl
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
string _wcfBasePath = "http://localhost:9002/Wcf/talk.svc/";
        
string _Ip = "";
        
private DispatcherTimer _timer;
       

        
public MainPage()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            InitializeComponent();
            GetIP();
            ShowLogin();          
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 格式化登录信息
        
/// </summary>
        
/// <returns></returns>

        string FormatLoginInfo()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string[] _arr = Helper.GetLoginInfo().Split('^');

            
return "欢迎回来 " + _arr[1+ "(" + _arr[2+ "),最近登录时间:" + _arr[3+ ",最近登录Ip:" + _arr[4];
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 显示登录面板
        
/// </summary>

        void ShowLogin()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (Helper.IsLogined())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                pnlLoginOk.Visibility 
= Visibility.Visible;
                pnlLogin.Visibility 
= Visibility.Collapsed;
                pnlReg.Visibility 
= Visibility.Collapsed;
                txtLoginOk.Text 
= FormatLoginInfo();

                
//向服务器在线列表中添加自己
                InsertOnline();

                
//获取历史聊天记录
                GetMessageList();

                
//获取最近联系人
                GetRecentList();


                
this._timer = new DispatcherTimer();
                
this._timer.Interval = new TimeSpan(005);
                
this._timer.Tick += new EventHandler(timer_Tick);
                
this._timer.Start();

            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                pnlLogin.Visibility 
= Visibility.Visible;
                pnlLoginOk.Visibility 
= Visibility.Collapsed;
                pnlReg.Visibility 
= Visibility.Collapsed;
            }



        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 出错提示
        
/// </summary>
        
/// <param name="title"></param>
        
/// <param name="content"></param>

        void ShowError(string title, string content)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//txtError.Text = "错误:" + err;
            
//pnlError.Visibility = Visibility.Visible;

            ChildWindow child 
= new ChildWindow();
            child.Title 
= title;
            child.Content 
= content;
            child.HasCloseButton 
= true;
            child.OverlayBrush 
= new SolidColorBrush(Colors.Gray);
            child.OverlayOpacity 
= 0.3;
            child.Width 
= 240;
            child.Height 
= 100;

            child.Show();
        }


        
void ShowError(string content)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            ShowError(
"错误", content);
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 获取当前客户端IP
        
/// </summary>

        private void GetIP()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Uri serviceUri 
= new Uri(_wcfBasePath + "GetIP?rnd=" + DateTime.Now.Ticks);
            WebClient client 
= new WebClient();
            client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(GetIpComplete);
            client.OpenReadAsync(serviceUri);
        }


        
void GetIpComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jResult 
= JsonArray.Load(e.Result);
                _Ip 
= _jResult["IP"].ToString().Trim('\"');
            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 用户登录
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void btnLogin_Click(object sender, System.Windows.RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{



            Uri serviceUri 
= new Uri(_wcfBasePath + "IsValidUser?loginName=" + HttpUtility.UrlEncode(txtLoginName.Text.Trim()) + "&pwd=" + HttpUtility.UrlEncode(txtPwd.Password.Trim()) + "&rnd=" + DateTime.Now.Ticks);
            WebClient client 
= new WebClient();
            client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(loginComplete);
            client.OpenReadAsync(serviceUri);
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 登录完毕回调函数
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        void loginComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jResult 
= JsonArray.Load(e.Result);

                
if (_jResult["Head"].Count == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    ShowError(
"登录失败,请检查用户名/密码");
                }

                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    var dr 
= _jResult["Head"][0];

                    T_User _user 
= new T_User();
                    _user.F_Id 
= int.Parse(dr["F_Id"].ToString().Trim('\"'));
                    
//_user.F_LastLoginDate = DateTime.Parse(dr["F_LastLoginDate"].ToString().Trim('\"'));
                    _user.F_LastLoginDate = DateTime.Now;
                    
//_user.F_LastLoginIP = dr["F_LastLoginIp"].ToString().Trim('\"');
                    _user.F_LastLoginIP = _Ip;
                    _user.F_LoginName 
= dr["F_LoginName"].ToString().Trim('\"');
                    _user.F_NickName 
= dr["F_NickName"].ToString().Trim('\"');
                    _user.F_Pwd 
= "";

                    Helper.WriteLoginInfo(_user);

                    pnlLoginOk.Visibility 
= Visibility.Visible;
                    pnlLogin.Visibility 
= Visibility.Collapsed;

                    txtLoginOk.Text 
= FormatLoginInfo();
                    InsertOnline();

                    
//获取历史聊天记录
                    GetMessageList();

                    
//获取最近联系人
                    GetRecentList();


                    
this._timer = new DispatcherTimer();
                    
this._timer.Interval = new TimeSpan(0005);
                    
this._timer.Tick += new EventHandler(timer_Tick);
                    
this._timer.Start();
                }


            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(e.Error.Message.ToString());
            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 返回登录 
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void btnBackToLogin_Click(object sender, RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            pnlReg.Visibility 
= Visibility.Collapsed;
            pnlLogin.Visibility 
= Visibility.Visible;
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 返回注册
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void btnGoToReg_Click(object sender, RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            pnlLogin.Visibility 
= Visibility.Collapsed;
            pnlReg.Visibility 
= Visibility.Visible;
        }



ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 退出
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void btnLogOut_Click(object sender, RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            pnlLogin.Visibility 
= Visibility.Visible;
            pnlLoginOk.Visibility 
= Visibility.Collapsed;
            DeleteOnline();
            Helper.DeleteLoginInfo();

            
if (_timer != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                _timer.Stop();
            }



        }



ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// (登录后)插入在线列表
        
/// </summary>

        void InsertOnline()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            Uri serviceUri 
= new Uri(_wcfBasePath + "InsertOnline?userid=" + HttpUtility.UrlEncode(_loginInfo[0]) + "&loginname=" + HttpUtility.UrlEncode(_loginInfo[1]) + "&nickname=" + HttpUtility.UrlEncode(_loginInfo[2]) + "&rnd=" + DateTime.Now.Ticks);
            WebClient client 
= new WebClient();
            client.OpenReadAsync(serviceUri);

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// (退出时)从在线列表清除
        
/// </summary>

        void DeleteOnline()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            Uri serviceUri 
= new Uri(_wcfBasePath + "DeleteOnline?userid=" + _loginInfo[0+ "&rnd=" + DateTime.Now.Ticks);
            WebClient client 
= new WebClient();
            client.OpenReadAsync(serviceUri);
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 点击"在线用户"时,更新在线列表
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void tblItemOnline_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Uri serviceUri 
= new Uri(_wcfBasePath + "GetOnlineList?&rnd=" + DateTime.Now.Ticks);
            WebClient client 
= new WebClient();
            client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(GetOnlineListComplete);
            client.OpenReadAsync(serviceUri);
        }



ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 取得在线列表回调函数
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        void GetOnlineListComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jsonValue 
= JsonArray.Load(e.Result);

                List
<KeyValuePair<intstring>> _list = new List<KeyValuePair<intstring>>();

                
if (_jsonValue["Head"].Count > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{

                    
for (int i = 0; i < _jsonValue["Head"].Count; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        _list.Add(
new KeyValuePair<intstring>(int.Parse(_jsonValue["Head"][i]["ID"].ToString().Trim('\"')), _jsonValue["Head"][i]["Name"].ToString().Trim('\"')));
                    }

                }

                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    _list.Add(
new KeyValuePair<intstring>(0"暂无在线用户"));
                }



                ListBox _listBox 
= new ListBox();
                _listBox.ItemsSource 
= _list;
                _listBox.DisplayMemberPath 
= "Value";
                _listBox.MouseLeftButtonUp 
+= new MouseButtonEventHandler(_listBox_MouseLeftButtonUp);
                ScrollViewer _viewer 
= new ScrollViewer();
                _viewer.Content 
= _listBox;
                _listBox.BorderThickness 
= new Thickness(0);
                
this.tblItemOnline.Content = _viewer;
                _viewer.Height 
= pnlTab.ActualHeight - 38;


                
//ListBox _listBox = new ListBox();
                
//_listBox.ItemsSource = _list;
                
//_listBox.DisplayMemberPath = "Value";
                
//this.tblItemOnline.Content = _listBox;

                
//_listBox.MouseLeftButtonUp += new MouseButtonEventHandler(_listBox_MouseLeftButtonUp);
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(e.Error.Message.ToString());
            }

        }



ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 列表框单击时显示“您正在跟xxx聊天”
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void _listBox_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            ListBox lstBox 
= sender as ListBox;
            KeyValuePair
<intstring> _keyValue = (KeyValuePair<intstring>)lstBox.SelectedItem;

ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (_keyValue.Key == 0return; }
            txtTarget.Text 
= _keyValue.Value;
            lblId.Content 
= _keyValue.Key.ToString();
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 用户注册
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void btnReg_Click(object sender, System.Windows.RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (this.txtRegName.Text == "")
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(
"请输入注册登录名!");
                
return;
            }



            
if (txtRegPwd.Password != txtRegPwd2.Password)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(
"二次密码输入不一致!");
                
return;
            }


            Uri serviceUri 
= new Uri(_wcfBasePath + "InsertUser?loginName=" + HttpUtility.UrlEncode(txtRegName.Text.Trim()) + "&nickName=" + HttpUtility.UrlEncode(this.txtNickName.Text.Trim()) + "&pwd=" + HttpUtility.UrlEncode(this.txtRegPwd.Password.Trim()) + "&rnd=" + DateTime.Now.Ticks);
            WebClient client 
= new WebClient();
            client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(RegComplete);
            client.OpenReadAsync(serviceUri);
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 注册完成回调函数
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        void RegComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jsonValue 
= JsonArray.Load(e.Result);
                
if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
//注册成功
                    ShowError("恭喜""注册成功,请登录!");
                    pnlLogin.Visibility 
= Visibility.Visible;
                    pnlReg.Visibility 
= Visibility.Collapsed;
                    txtLoginName.Text 
= txtRegName.Text;
                    txtPwd.Password 
= txtRegPwd.Password;


                }

                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    ShowError(
"注册失败:" + _jsonValue["detail"].ToString().Trim('\"'));
                }

            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(e.Error.Message.ToString());
            }

        }



ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 点击"我的好友"时,更新列表
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void tblItemMyFriend_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string[] _loginInfo = Helper.GetLoginInfo().Split('^');

            
int _userId = 0;

            
if (int.TryParse(_loginInfo[0].ToString(), out _userId))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Uri serviceUri 
= new Uri(_wcfBasePath + "GetFriendList?userId=" + _loginInfo[0+ "&rnd=" + DateTime.Now.Ticks);
                WebClient client 
= new WebClient();
                client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(GetFriendListComplete);
                client.OpenReadAsync(serviceUri);
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                tblItemMyFriend.Content 
= "尚未添加任何好友";
            }



        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 获取好友列表回调函数
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        void GetFriendListComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jsonValue 
= JsonArray.Load(e.Result);

                List
<KeyValuePair<intstring>> _list = new List<KeyValuePair<intstring>>();

                
if (_jsonValue["Head"].Count > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{

                    
for (int i = 0; i < _jsonValue["Head"].Count; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        _list.Add(
new KeyValuePair<intstring>(int.Parse(_jsonValue["Head"][i]["ID"].ToString().Trim('\"')), _jsonValue["Head"][i]["Name"].ToString().Trim('\"')));
                    }

                }

                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    _list.Add(
new KeyValuePair<intstring>(0"尚未添加任何好友"));
                }


                ListBox _listBox 
= new ListBox();
                _listBox.ItemsSource 
= _list;
                _listBox.DisplayMemberPath 
= "Value";
                _listBox.MouseLeftButtonUp 
+= new MouseButtonEventHandler(_listBox_MouseLeftButtonUp);
                ScrollViewer _viewer 
= new ScrollViewer();
                _viewer.Content 
= _listBox;
                _listBox.BorderThickness 
= new Thickness(0);
                
this.tblItemMyFriend.Content = _viewer;
                _viewer.Height 
= pnlTab.ActualHeight - 38;
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(e.Error.Message.ToString());
            }

        }



ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 发送消息
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void btnSend_Click(object sender, System.Windows.RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string[] _loginInfo = Helper.GetLoginInfo().Split('^');

            
int _userId = 0;

            
if (int.TryParse(_loginInfo[0].ToString(), out _userId))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
int _receiverId = 0;

                
if (int.TryParse(this.lblId.Content.ToString(), out _receiverId))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
if (_userId == _receiverId)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        ShowError(
"自己不能跟自己聊天!");
                        
return;
                    }


                    
if (txtContent.Text.Trim() == "")
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        ShowError(
"请输入聊天内容!");
                    }

                    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        Uri serviceUri 
= new Uri(_wcfBasePath + "SendMsg?senderId=" + _userId + "&receiverId=" + _receiverId + "&content=" + HttpUtility.UrlEncode(this.txtContent.Text) + "&rnd=" + DateTime.Now.Ticks);
                        WebClient client 
= new WebClient();
                        client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(SendMsgComplete);
                        client.OpenReadAsync(serviceUri);
                    }

                }

                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    ShowError(
"请先从右侧列表中选择一个聊天对象");
                }


            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(
"请先登录");
            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 发送消息回调函数
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        void SendMsgComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jsonValue 
= JsonArray.Load(e.Result);

                
if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
this.txtContent.Text = "";
                    GetMessageList();
                }

            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(e.Error.Message.ToString());
            }

        }



ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 获取消息记录
        
/// </summary>

        void GetMessageList()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string[] _loginInfo = Helper.GetLoginInfo().Split('^');

            
int _userId = 0;

            
if (int.TryParse(_loginInfo[0].ToString(), out _userId))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Uri serviceUri 
= new Uri(_wcfBasePath + "GetMessageList?userId=" + _userId + "&rnd=" + DateTime.Now.Ticks);
                WebClient client 
= new WebClient();
                client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(GetMessageListComplete);
                client.OpenReadAsync(serviceUri);
            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 取得消息列表回调函数
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        void GetMessageListComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jsonValue 
= JsonArray.Load(e.Result);

                StringBuilder sb 
= new StringBuilder();

                
if (_jsonValue["Head"].Count > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
                    
string _senderName = _loginInfo[1+ "(" + _loginInfo[2+ ")";

                    
for (int i = 0; i < _jsonValue["Head"].Count; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
string _s = _jsonValue["Head"][i]["F_SenderName"].ToString().Trim('\"');
                        
if (_s == _senderName)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
{
                            _s 
= "";
                        }


                        
string _r = _jsonValue["Head"][i]["F_ReceiverName"].ToString().Trim('\"');
                        
if (_r == _senderName)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
{
                            _r 
= "";
                        }


                        sb.Append(_s 
+ " 于 " + _jsonValue["Head"][i]["F_Date"].ToString().Trim('\"'+ " 对 " + _r + " 说:" + Environment.NewLine + _jsonValue["Head"][i]["F_Content"].ToString().Trim('\"'+ Environment.NewLine + Environment.NewLine);
                    }


                    txtRecord.Text 
= sb.ToString();
                    txtRecord.SelectAll();
                }



            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(e.Error.Message.ToString());
            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 取得最近联系人列表
        
/// </summary>

        void GetRecentList()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string[] _loginInfo = Helper.GetLoginInfo().Split('^');

            
int _userId = 0;

            
if (int.TryParse(_loginInfo[0].ToString(), out _userId))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Uri serviceUri 
= new Uri(_wcfBasePath + "GetRecent?userId=" + _userId + "&rnd=" + DateTime.Now.Ticks);
                WebClient client 
= new WebClient();
                client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(GetRecentListComplete);
                client.OpenReadAsync(serviceUri);
            }

            
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                tblItemRecently.Content 
= "暂无联系人信息";
            }

        }



ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 取得最近联系人列表回调函数
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        void GetRecentListComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jsonValue 
= JsonArray.Load(e.Result);

                List
<KeyValuePair<intstring>> _list = new List<KeyValuePair<intstring>>();

                
if (_jsonValue["Head"].Count > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{

                    
for (int i = 0; i < _jsonValue["Head"].Count; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        _list.Add(
new KeyValuePair<intstring>(int.Parse(_jsonValue["Head"][i]["ID"].ToString().Trim('\"')), _jsonValue["Head"][i]["Name"].ToString().Trim('\"')));
                    }

                }

                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    _list.Add(
new KeyValuePair<intstring>(0"暂无任何人给你发消息"));
                }


                ListBox _listBox 
= new ListBox();
                _listBox.ItemsSource 
= _list;
                _listBox.DisplayMemberPath 
= "Value";
                _listBox.MouseLeftButtonUp 
+= new MouseButtonEventHandler(_listBox_MouseLeftButtonUp);
                ScrollViewer _viewer 
= new ScrollViewer();
                _viewer.Content 
= _listBox;
                _listBox.BorderThickness 
= new Thickness(0);
                
this.tblItemRecently.Content = _viewer;
                _viewer.Height 
= pnlTab.ActualHeight - 38;
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(e.Error.Message.ToString());
            }

        }


        
private void txtContent_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            ModifierKeys keys 
= Keyboard.Modifiers;

            
if (e.Key == Key.Enter && keys == ModifierKeys.Control)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                btnSend_Click(sender, e);
            }

        }


        
private void tblItemRecently_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            GetRecentList();
        }


        
private void txtContent_GotFocus(object sender, System.Windows.RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string[] _loginInfo = Helper.GetLoginInfo().Split('^');

            
int _myId = 0;

            
if (int.TryParse(_loginInfo[0].ToString(), out _myId))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
int _otherId = 0;

                
if (int.TryParse(this.lblId.Content.ToString(), out _otherId))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
if (_myId == _otherId)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
return;
                    }


                    Uri serviceUri 
= new Uri(_wcfBasePath + "IsFriend?myId=" + _myId + "&otherId=" + _otherId + "&rnd=" + DateTime.Now.Ticks);
                    WebClient client 
= new WebClient();
                    client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(IsFriendComplete);
                    client.OpenReadAsync(serviceUri);

                }


            }


        }



        
void IsFriendComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jsonValue 
= JsonArray.Load(e.Result);

                List
<KeyValuePair<intstring>> _list = new List<KeyValuePair<intstring>>();

                
if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
this.btnDeleteFriend.Visibility = Visibility.Visible;
                    
this.btnAddFriend.Visibility = Visibility.Collapsed;
                }

                
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
this.btnAddFriend.Visibility = Visibility.Visible;
                    
this.btnDeleteFriend.Visibility = Visibility.Collapsed;
                }

            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(e.Error.Message.ToString());
            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 加为好友
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void btnAddFriend_Click(object sender, System.Windows.RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string[] _loginInfo = Helper.GetLoginInfo().Split('^');

            
int _myId = 0;

            
if (int.TryParse(_loginInfo[0].ToString(), out _myId))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
int _otherId = 0;

                
if (int.TryParse(this.lblId.Content.ToString(), out _otherId))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
if (_myId == _otherId)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
return;
                    }


                    Uri serviceUri 
= new Uri(_wcfBasePath + "InsertFriend?myId=" + _myId + "&otherId=" + _otherId + "&rnd=" + DateTime.Now.Ticks);
                    WebClient client 
= new WebClient();
                    client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(AddFriendComplete);
                    client.OpenReadAsync(serviceUri);

                    btnAddFriend.Visibility 
= Visibility.Collapsed;

                }


            }

        }

        
        
        
void AddFriendComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jsonValue 
= JsonArray.Load(e.Result);

ExpandedSubBlockStart.gifContractedSubBlock.gif                
if (bool.Parse(_jsonValue["result"].ToString().Trim('\"'))){
                    
this.tblItemMyFriend_MouseLeftButtonUp(sender,null);
                }

            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(e.Error.Message.ToString());
            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 删除好友
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void btnDeleteFriend_Click(object sender, System.Windows.RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string[] _loginInfo = Helper.GetLoginInfo().Split('^');

            
int _myId = 0;

            
if (int.TryParse(_loginInfo[0].ToString(), out _myId))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
int _otherId = 0;

                
if (int.TryParse(this.lblId.Content.ToString(), out _otherId))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
if (_myId == _otherId)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
return;
                    }


                    Uri serviceUri 
= new Uri(_wcfBasePath + "DeleteFriend?myId=" + _myId + "&otherId=" + _otherId + "&rnd=" + DateTime.Now.Ticks);
                    WebClient client 
= new WebClient();
                    client.OpenReadCompleted 
+= new OpenReadCompletedEventHandler(DeleteFriendComplete);
                    client.OpenReadAsync(serviceUri);

                    btnDeleteFriend.Visibility 
= Visibility.Collapsed;


                }


            }

        }

        
        
        


        
void DeleteFriendComplete(object sender, OpenReadCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                JsonValue _jsonValue 
= JsonArray.Load(e.Result);

                
if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
this.tblItemMyFriend_MouseLeftButtonUp(sender, null);
                }

            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ShowError(e.Error.Message.ToString());
            }

        }




        
void timer_Tick(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            GetMessageList();
        }


        
private void txtContent_LostFocus(object sender, System.Windows.RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.btnAddFriend.Visibility = Visibility.Collapsed;
            
this.btnDeleteFriend.Visibility = Visibility.Collapsed;            
        }


       

        

    }

}

 

ContractedBlock.gif ExpandedBlockStart.gif 数据库表结构
 1CREATE TABLE [dbo].[T_User](
 2    [F_Id] [int] IDENTITY(1,1NOT NULL,
 3    [F_LoginName] [nvarchar](50NOT NULL,
 4    [F_NickName] [nvarchar](100NOT NULL,
 5    [F_Pwd] [nvarchar](50NOT NULL,
 6    [F_LastLoginDate] [datetime] NOT NULL,
 7    [F_LastLoginIP] [nvarchar](50NOT NULL,
 8 CONSTRAINT [PK_T_User] PRIMARY KEY CLUSTERED 
 9(
10    [F_Id] ASC
11)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]
12ON [PRIMARY]
13
14
15CREATE TABLE [dbo].[T_Message](
16    [F_Id] [int] IDENTITY(1,1NOT NULL,
17    [F_ReceiverId] [int] NOT NULL,
18    [F_SenderId] [int] NOT NULL,
19    [F_Content] [nvarchar](maxNOT NULL,
20    [F_Date] [datetime] NOT NULL,
21 CONSTRAINT [PK_T_Message] PRIMARY KEY CLUSTERED 
22(
23    [F_Id] ASC
24)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]
25ON [PRIMARY]
26
27GO
28ALTER TABLE [dbo].[T_Message]  WITH CHECK ADD  CONSTRAINT [FK_T_Message_T_User] FOREIGN KEY([F_ReceiverId])
29REFERENCES [dbo].[T_User] ([F_Id])
30ON UPDATE CASCADE
31ON DELETE CASCADE
32GO
33ALTER TABLE [dbo].[T_Message] CHECK CONSTRAINT [FK_T_Message_T_User]
34
35CREATE TABLE [dbo].[T_Friend](
36    [F_Id] [int] IDENTITY(1,1NOT NULL,
37    [F_UserId] [int] NOT NULL,
38    [F_FriendId] [int] NOT NULL,
39 CONSTRAINT [PK_T_Friend] PRIMARY KEY CLUSTERED 
40(
41    [F_Id] ASC
42)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]
43ON [PRIMARY]
44
45GO
46ALTER TABLE [dbo].[T_Friend]  WITH CHECK ADD  CONSTRAINT [FK_T_Friend_T_User1] FOREIGN KEY([F_UserId])
47REFERENCES [dbo].[T_User] ([F_Id])
48ON UPDATE CASCADE
49ON DELETE CASCADE
50GO
51ALTER TABLE [dbo].[T_Friend] CHECK CONSTRAINT [FK_T_Friend_T_User1]

 本来是要把源代码放上来了,一来是因为完全是用来练手的,代码写得比较乱,二来这里面用到了公司的一些现成工具库的dll,不方便对外发布,所以只能把主要代码贴出来,其实只要弄懂了原理,大家完全可以自己从头开发一遍,说穿了就是silverlight + wcf + timer来读写数据库,没有太多的技术含量

转载于:https://www.cnblogs.com/yjmyzz/archive/2009/08/31/1557052.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值