基于sliverlight + wcf的web 文字版IM 示例
预览界面:
一、布局
采用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,呵
四、代码
代码有点乱,也相对比较长,关键代码全部折叠贴在下面了:
<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>
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
{
public partial class MainPage : UserControl
{
string _wcfBasePath = "http://localhost:9002/Wcf/talk.svc/";
string _Ip = "";
private DispatcherTimer _timer;
public MainPage()
{
InitializeComponent();
GetIP();
ShowLogin();
}
/**//// <summary>
/// 格式化登录信息
/// </summary>
/// <returns></returns>
string FormatLoginInfo()
{
string[] _arr = Helper.GetLoginInfo().Split('^');
return "欢迎回来 " + _arr[1] + "(" + _arr[2] + "),最近登录时间:" + _arr[3] + ",最近登录Ip:" + _arr[4];
}
/**//// <summary>
/// 显示登录面板
/// </summary>
void ShowLogin()
{
if (Helper.IsLogined())
{
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(0, 0, 5);
this._timer.Tick += new EventHandler(timer_Tick);
this._timer.Start();
}
else
{
pnlLogin.Visibility = Visibility.Visible;
pnlLoginOk.Visibility = Visibility.Collapsed;
pnlReg.Visibility = Visibility.Collapsed;
}
}
/**//// <summary>
/// 出错提示
/// </summary>
/// <param name="title"></param>
/// <param name="content"></param>
void ShowError(string title, string content)
{
//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)
{
ShowError("错误", content);
}
/**//// <summary>
/// 获取当前客户端IP
/// </summary>
private void GetIP()
{
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)
{
if (e.Error == null)
{
JsonValue _jResult = JsonArray.Load(e.Result);
_Ip = _jResult["IP"].ToString().Trim('\"');
}
}
/**//// <summary>
/// 用户登录
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnLogin_Click(object sender, System.Windows.RoutedEventArgs e)
{
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);
}
/**//// <summary>
/// 登录完毕回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void loginComplete(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
JsonValue _jResult = JsonArray.Load(e.Result);
if (_jResult["Head"].Count == 0)
{
ShowError("登录失败,请检查用户名/密码");
}
else
{
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(0, 0, 0, 5);
this._timer.Tick += new EventHandler(timer_Tick);
this._timer.Start();
}
}
else
{
ShowError(e.Error.Message.ToString());
}
}
/**//// <summary>
/// 返回登录
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnBackToLogin_Click(object sender, RoutedEventArgs e)
{
pnlReg.Visibility = Visibility.Collapsed;
pnlLogin.Visibility = Visibility.Visible;
}
/**//// <summary>
/// 返回注册
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnGoToReg_Click(object sender, RoutedEventArgs e)
{
pnlLogin.Visibility = Visibility.Collapsed;
pnlReg.Visibility = Visibility.Visible;
}
/**//// <summary>
/// 退出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnLogOut_Click(object sender, RoutedEventArgs e)
{
pnlLogin.Visibility = Visibility.Visible;
pnlLoginOk.Visibility = Visibility.Collapsed;
DeleteOnline();
Helper.DeleteLoginInfo();
if (_timer != null)
{
_timer.Stop();
}
}
/**//// <summary>
/// (登录后)插入在线列表
/// </summary>
void InsertOnline()
{
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);
}
/**//// <summary>
/// (退出时)从在线列表清除
/// </summary>
void DeleteOnline()
{
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);
}
/**//// <summary>
/// 点击"在线用户"时,更新在线列表
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tblItemOnline_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Uri serviceUri = new Uri(_wcfBasePath + "GetOnlineList?&rnd=" + DateTime.Now.Ticks);
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(GetOnlineListComplete);
client.OpenReadAsync(serviceUri);
}
/**//// <summary>
/// 取得在线列表回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void GetOnlineListComplete(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
JsonValue _jsonValue = JsonArray.Load(e.Result);
List<KeyValuePair<int, string>> _list = new List<KeyValuePair<int, string>>();
if (_jsonValue["Head"].Count > 0)
{
for (int i = 0; i < _jsonValue["Head"].Count; i++)
{
_list.Add(new KeyValuePair<int, string>(int.Parse(_jsonValue["Head"][i]["ID"].ToString().Trim('\"')), _jsonValue["Head"][i]["Name"].ToString().Trim('\"')));
}
}
else
{
_list.Add(new KeyValuePair<int, string>(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
{
ShowError(e.Error.Message.ToString());
}
}
/**//// <summary>
/// 列表框单击时显示“您正在跟xxx聊天”
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _listBox_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ListBox lstBox = sender as ListBox;
KeyValuePair<int, string> _keyValue = (KeyValuePair<int, string>)lstBox.SelectedItem;
if (_keyValue.Key == 0) { return; }
txtTarget.Text = _keyValue.Value;
lblId.Content = _keyValue.Key.ToString();
}
/**//// <summary>
/// 用户注册
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnReg_Click(object sender, System.Windows.RoutedEventArgs e)
{
if (this.txtRegName.Text == "")
{
ShowError("请输入注册登录名!");
return;
}
if (txtRegPwd.Password != txtRegPwd2.Password)
{
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);
}
/**//// <summary>
/// 注册完成回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void RegComplete(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
JsonValue _jsonValue = JsonArray.Load(e.Result);
if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
{
//注册成功
ShowError("恭喜", "注册成功,请登录!");
pnlLogin.Visibility = Visibility.Visible;
pnlReg.Visibility = Visibility.Collapsed;
txtLoginName.Text = txtRegName.Text;
txtPwd.Password = txtRegPwd.Password;
}
else
{
ShowError("注册失败:" + _jsonValue["detail"].ToString().Trim('\"'));
}
}
else
{
ShowError(e.Error.Message.ToString());
}
}
/**//// <summary>
/// 点击"我的好友"时,更新列表
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tblItemMyFriend_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
int _userId = 0;
if (int.TryParse(_loginInfo[0].ToString(), out _userId))
{
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
{
tblItemMyFriend.Content = "尚未添加任何好友";
}
}
/**//// <summary>
/// 获取好友列表回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void GetFriendListComplete(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
JsonValue _jsonValue = JsonArray.Load(e.Result);
List<KeyValuePair<int, string>> _list = new List<KeyValuePair<int, string>>();
if (_jsonValue["Head"].Count > 0)
{
for (int i = 0; i < _jsonValue["Head"].Count; i++)
{
_list.Add(new KeyValuePair<int, string>(int.Parse(_jsonValue["Head"][i]["ID"].ToString().Trim('\"')), _jsonValue["Head"][i]["Name"].ToString().Trim('\"')));
}
}
else
{
_list.Add(new KeyValuePair<int, string>(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
{
ShowError(e.Error.Message.ToString());
}
}
/**//// <summary>
/// 发送消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, System.Windows.RoutedEventArgs e)
{
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
int _userId = 0;
if (int.TryParse(_loginInfo[0].ToString(), out _userId))
{
int _receiverId = 0;
if (int.TryParse(this.lblId.Content.ToString(), out _receiverId))
{
if (_userId == _receiverId)
{
ShowError("自己不能跟自己聊天!");
return;
}
if (txtContent.Text.Trim() == "")
{
ShowError("请输入聊天内容!");
}
else
{
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
{
ShowError("请先从右侧列表中选择一个聊天对象");
}
}
else
{
ShowError("请先登录");
}
}
/**//// <summary>
/// 发送消息回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void SendMsgComplete(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
JsonValue _jsonValue = JsonArray.Load(e.Result);
if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
{
this.txtContent.Text = "";
GetMessageList();
}
}
else
{
ShowError(e.Error.Message.ToString());
}
}
/**//// <summary>
/// 获取消息记录
/// </summary>
void GetMessageList()
{
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
int _userId = 0;
if (int.TryParse(_loginInfo[0].ToString(), out _userId))
{
Uri serviceUri = new Uri(_wcfBasePath + "GetMessageList?userId=" + _userId + "&rnd=" + DateTime.Now.Ticks);
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(GetMessageListComplete);
client.OpenReadAsync(serviceUri);
}
}
/**//// <summary>
/// 取得消息列表回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void GetMessageListComplete(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
JsonValue _jsonValue = JsonArray.Load(e.Result);
StringBuilder sb = new StringBuilder();
if (_jsonValue["Head"].Count > 0)
{
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
string _senderName = _loginInfo[1] + "(" + _loginInfo[2] + ")";
for (int i = 0; i < _jsonValue["Head"].Count; i++)
{
string _s = _jsonValue["Head"][i]["F_SenderName"].ToString().Trim('\"');
if (_s == _senderName)
{
_s = "我";
}
string _r = _jsonValue["Head"][i]["F_ReceiverName"].ToString().Trim('\"');
if (_r == _senderName)
{
_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
{
ShowError(e.Error.Message.ToString());
}
}
/**//// <summary>
/// 取得最近联系人列表
/// </summary>
void GetRecentList()
{
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
int _userId = 0;
if (int.TryParse(_loginInfo[0].ToString(), out _userId))
{
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
{
tblItemRecently.Content = "暂无联系人信息";
}
}
/**//// <summary>
/// 取得最近联系人列表回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void GetRecentListComplete(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
JsonValue _jsonValue = JsonArray.Load(e.Result);
List<KeyValuePair<int, string>> _list = new List<KeyValuePair<int, string>>();
if (_jsonValue["Head"].Count > 0)
{
for (int i = 0; i < _jsonValue["Head"].Count; i++)
{
_list.Add(new KeyValuePair<int, string>(int.Parse(_jsonValue["Head"][i]["ID"].ToString().Trim('\"')), _jsonValue["Head"][i]["Name"].ToString().Trim('\"')));
}
}
else
{
_list.Add(new KeyValuePair<int, string>(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
{
ShowError(e.Error.Message.ToString());
}
}
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);
}
}
private void tblItemRecently_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
GetRecentList();
}
private void txtContent_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
int _myId = 0;
if (int.TryParse(_loginInfo[0].ToString(), out _myId))
{
int _otherId = 0;
if (int.TryParse(this.lblId.Content.ToString(), out _otherId))
{
if (_myId == _otherId)
{
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)
{
if (e.Error == null)
{
JsonValue _jsonValue = JsonArray.Load(e.Result);
List<KeyValuePair<int, string>> _list = new List<KeyValuePair<int, string>>();
if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
{
this.btnDeleteFriend.Visibility = Visibility.Visible;
this.btnAddFriend.Visibility = Visibility.Collapsed;
}
else
{
this.btnAddFriend.Visibility = Visibility.Visible;
this.btnDeleteFriend.Visibility = Visibility.Collapsed;
}
}
else
{
ShowError(e.Error.Message.ToString());
}
}
/**//// <summary>
/// 加为好友
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAddFriend_Click(object sender, System.Windows.RoutedEventArgs e)
{
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
int _myId = 0;
if (int.TryParse(_loginInfo[0].ToString(), out _myId))
{
int _otherId = 0;
if (int.TryParse(this.lblId.Content.ToString(), out _otherId))
{
if (_myId == _otherId)
{
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)
{
if (e.Error == null)
{
JsonValue _jsonValue = JsonArray.Load(e.Result);
if (bool.Parse(_jsonValue["result"].ToString().Trim('\"'))){
this.tblItemMyFriend_MouseLeftButtonUp(sender,null);
}
}
else
{
ShowError(e.Error.Message.ToString());
}
}
/**//// <summary>
/// 删除好友
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnDeleteFriend_Click(object sender, System.Windows.RoutedEventArgs e)
{
string[] _loginInfo = Helper.GetLoginInfo().Split('^');
int _myId = 0;
if (int.TryParse(_loginInfo[0].ToString(), out _myId))
{
int _otherId = 0;
if (int.TryParse(this.lblId.Content.ToString(), out _otherId))
{
if (_myId == _otherId)
{
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)
{
if (e.Error == null)
{
JsonValue _jsonValue = JsonArray.Load(e.Result);
if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
{
this.tblItemMyFriend_MouseLeftButtonUp(sender, null);
}
}
else
{
ShowError(e.Error.Message.ToString());
}
}
void timer_Tick(object sender, EventArgs e)
{
GetMessageList();
}
private void txtContent_LostFocus(object sender, System.Windows.RoutedEventArgs e)
{
this.btnAddFriend.Visibility = Visibility.Collapsed;
this.btnDeleteFriend.Visibility = Visibility.Collapsed;
}
}
}
1CREATE TABLE [dbo].[T_User](
2 [F_Id] [int] IDENTITY(1,1) NOT NULL,
3 [F_LoginName] [nvarchar](50) NOT NULL,
4 [F_NickName] [nvarchar](100) NOT NULL,
5 [F_Pwd] [nvarchar](50) NOT NULL,
6 [F_LastLoginDate] [datetime] NOT NULL,
7 [F_LastLoginIP] [nvarchar](50) NOT 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 = ON) ON [PRIMARY]
12) ON [PRIMARY]
13
14
15CREATE TABLE [dbo].[T_Message](
16 [F_Id] [int] IDENTITY(1,1) NOT NULL,
17 [F_ReceiverId] [int] NOT NULL,
18 [F_SenderId] [int] NOT NULL,
19 [F_Content] [nvarchar](max) NOT 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 = ON) ON [PRIMARY]
25) ON [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,1) NOT 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 = ON) ON [PRIMARY]
43) ON [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来读写数据库,没有太多的技术含量
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。