Quellcode durchsuchen

添加项目文件。

master
王晓寒 vor 6 Monaten
Ursprung
Commit
9769de2b85
100 geänderte Dateien mit 8256 neuen und 0 gelöschten Zeilen
  1. +6
    -0
      ConsoleApp/App.config
  2. +88
    -0
      ConsoleApp/ConsoleApp.csproj
  3. +279
    -0
      ConsoleApp/Program.cs
  4. +36
    -0
      ConsoleApp/Properties/AssemblyInfo.cs
  5. +4
    -0
      ConsoleApp/packages.config
  6. +72
    -0
      GoChat.Controls/CommandBase.cs
  7. +322
    -0
      GoChat.Controls/ControlAttachProperty.cs
  8. +24
    -0
      GoChat.Controls/ExCommandParameter.cs
  9. +134
    -0
      GoChat.Controls/ExInvokeCommandAction.cs
  10. +208
    -0
      GoChat.Controls/GoChat.Controls.csproj
  11. +182
    -0
      GoChat.Controls/GoChatButton.cs
  12. +25
    -0
      GoChat.Controls/GoChatTabControl.cs
  13. +44
    -0
      GoChat.Controls/GoChatTabItem.cs
  14. +44
    -0
      GoChat.Controls/GoChatTextBox.cs
  15. +311
    -0
      GoChat.Controls/GoChatWin.cs
  16. +80
    -0
      GoChat.Controls/PasswordBoxHelper.cs
  17. +66
    -0
      GoChat.Controls/PasswordBoxWaterMark.cs
  18. +129
    -0
      GoChat.Controls/PromptAdorner.cs
  19. +31
    -0
      GoChat.Controls/PromptChrome.cs
  20. +55
    -0
      GoChat.Controls/Properties/AssemblyInfo.cs
  21. +63
    -0
      GoChat.Controls/Properties/Resources.Designer.cs
  22. +117
    -0
      GoChat.Controls/Properties/Resources.resx
  23. +26
    -0
      GoChat.Controls/Properties/Settings.Designer.cs
  24. +7
    -0
      GoChat.Controls/Properties/Settings.settings
  25. BIN
      GoChat.Controls/Resources/Images/01.png
  26. BIN
      GoChat.Controls/Resources/Images/02.png
  27. BIN
      GoChat.Controls/Resources/Images/03.png
  28. BIN
      GoChat.Controls/Resources/Images/mie.png
  29. BIN
      GoChat.Controls/Resources/Images/mim.png
  30. BIN
      GoChat.Controls/Resources/Images/min.png
  31. BIN
      GoChat.Controls/Resources/Images/mme.png
  32. BIN
      GoChat.Controls/Resources/Images/mmm.png
  33. BIN
      GoChat.Controls/Resources/Images/mmn.png
  34. BIN
      GoChat.Controls/Resources/Images/mxe.png
  35. BIN
      GoChat.Controls/Resources/Images/mxm.png
  36. BIN
      GoChat.Controls/Resources/Images/mxn.png
  37. BIN
      GoChat.Controls/Resources/Images/ske.png
  38. BIN
      GoChat.Controls/Resources/Images/skm.png
  39. BIN
      GoChat.Controls/Resources/Images/skn.png
  40. BIN
      GoChat.Controls/Resources/Images/xe.png
  41. BIN
      GoChat.Controls/Resources/Images/xm.png
  42. BIN
      GoChat.Controls/Resources/Images/xn.png
  43. BIN
      GoChat.Controls/Resources/fontawesome/1.png
  44. BIN
      GoChat.Controls/Resources/fontawesome/2.png
  45. BIN
      GoChat.Controls/Resources/fontawesome/3.png
  46. BIN
      GoChat.Controls/Resources/fontawesome/4.png
  47. BIN
      GoChat.Controls/Resources/fontawesome/5.png
  48. BIN
      GoChat.Controls/Resources/fontawesome/FontAwesome.otf
  49. +8
    -0
      GoChat.Controls/Themes/FontIcon.xaml
  50. +24
    -0
      GoChat.Controls/Themes/Generic.xaml
  51. +72
    -0
      GoChat.Controls/Themes/GoChatBulletCheckBox.xaml
  52. +61
    -0
      GoChat.Controls/Themes/GoChatBulletCheckBox.xaml.cs
  53. +238
    -0
      GoChat.Controls/Themes/GoChatButton.xaml
  54. +395
    -0
      GoChat.Controls/Themes/GoChatComboBox.xaml
  55. +262
    -0
      GoChat.Controls/Themes/GoChatListBox.xaml
  56. +181
    -0
      GoChat.Controls/Themes/GoChatMenu.xaml
  57. +81
    -0
      GoChat.Controls/Themes/GoChatPasswordBox.xaml
  58. +89
    -0
      GoChat.Controls/Themes/GoChatRichTextBox.xaml
  59. +516
    -0
      GoChat.Controls/Themes/GoChatScrollViewer.xaml
  60. +51
    -0
      GoChat.Controls/Themes/GoChatTabControl.xaml
  61. +145
    -0
      GoChat.Controls/Themes/GoChatTabItem.xaml
  62. +88
    -0
      GoChat.Controls/Themes/GoChatTextBox.xaml
  63. +107
    -0
      GoChat.Controls/Themes/GoChatToggleButton.xaml
  64. +22
    -0
      GoChat.Controls/Themes/GoChatToolTip.xaml
  65. +136
    -0
      GoChat.Controls/Themes/GoChatTreeView.xaml
  66. +335
    -0
      GoChat.Controls/Themes/GoChatWin.xaml
  67. +76
    -0
      GoChat.Controls/Themes/PromptChrome.xaml
  68. +69
    -0
      GoChat.Controls/WinStateBehavior.cs
  69. +4
    -0
      GoChat.Controls/packages.config
  70. +17
    -0
      GoChat.Infrastructure/CommonException.cs
  71. +106
    -0
      GoChat.Infrastructure/DESEncrypt.cs
  72. +67
    -0
      GoChat.Infrastructure/EnumExtensions.cs
  73. +74
    -0
      GoChat.Infrastructure/GoChat.Infrastructure.csproj
  74. +54
    -0
      GoChat.Infrastructure/Md5Helper.cs
  75. +97
    -0
      GoChat.Infrastructure/MemoryOptimization.cs
  76. +65
    -0
      GoChat.Infrastructure/ObjectExtensions.cs
  77. +36
    -0
      GoChat.Infrastructure/Properties/AssemblyInfo.cs
  78. +519
    -0
      GoChat.Infrastructure/SqLiteHelper.cs
  79. +83
    -0
      GoChat.Infrastructure/TypeExtensions.cs
  80. +4
    -0
      GoChat.Infrastructure/packages.config
  81. +13
    -0
      GoChat.Models/ChageCountEventArgs.cs
  82. +21
    -0
      GoChat.Models/ChatHistoryModel.cs
  83. +14
    -0
      GoChat.Models/ContactType.cs
  84. +20
    -0
      GoChat.Models/Dict.cs
  85. +124
    -0
      GoChat.Models/Enumerations.cs
  86. +17
    -0
      GoChat.Models/FontFamilyList.cs
  87. +25
    -0
      GoChat.Models/FontSizeList.cs
  88. +107
    -0
      GoChat.Models/GoChat.Models.csproj
  89. +80
    -0
      GoChat.Models/GroupModel.cs
  90. +188
    -0
      GoChat.Models/NetDiskFile/BaseFile.cs
  91. +356
    -0
      GoChat.Models/NetDiskFile/DownloadNetDiskFile.cs
  92. +216
    -0
      GoChat.Models/NetDiskFile/FileHistory.cs
  93. +11
    -0
      GoChat.Models/NetDiskFile/IDownload.cs
  94. +9
    -0
      GoChat.Models/NetDiskFile/IFile.cs
  95. +44
    -0
      GoChat.Models/NetDiskFile/NetDiskFile.cs
  96. +391
    -0
      GoChat.Models/NetDiskFile/UploadNetDiskFile.cs
  97. +45
    -0
      GoChat.Models/PersonalFontStyle.cs
  98. +37
    -0
      GoChat.Models/Properties/AssemblyInfo.cs
  99. +64
    -0
      GoChat.Models/SearchFriendOrGroupModel.cs
  100. +39
    -0
      GoChat.Models/Skin.cs

+ 6
- 0
ConsoleApp/App.config Datei anzeigen

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>

+ 88
- 0
ConsoleApp/ConsoleApp.csproj Datei anzeigen

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{572742EF-632B-452E-9D47-3A81ADBF55F5}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ConsoleApp</RootNamespace>
<AssemblyName>ConsoleApp</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<SccProjectName>ConsoleApp</SccProjectName>
<SccLocalPath>1~a7250b02-76e9-4d74-aa27-f5cdf7719296</SccLocalPath>
<SccAuxPath>http://123.57.209.16:8090/VaultService</SccAuxPath>
<SccProvider>SourceGear Vault Visual Studio 2005 Client:{1EA47954-8515-402d-82D9-B5C332120A8D}</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5.2 %28x86 和 x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

+ 279
- 0
ConsoleApp/Program.cs Datei anzeigen

@@ -0,0 +1,279 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
//
//string ss = HttpPost("http://localhost:18324/DiskFileApi/AddDiskFiles", "{FileName:\"api测试文件123.txt\",FileSaveName:\"api测试文件save123\",FolderId:6,UserId:100001005,FileType:\"文本\",FileSize:23456,ExtendName:\".txt\"}");

var model = new DiskFileModel
{
FileName = "api测试文件123.txt",
FileSaveName = "api测试文件save123.txt",
FolderId = 37,
UserId = 100001005,
FileType = "文本",
FileSize = 2345741,
ExtendName = ".txt"
};
var json = JsonConvert.SerializeObject(model);
//string ss = HttpPost("http://localhost:18324/api/savefile", json);
string ss = HttpPost("http://60.205.171.92:8888/api/savefile", json);
//string ss = HttpPost("http://192.168.1.125:8866/api/savefile", json);
Console.WriteLine(ss);
//WebClient webClient = new WebClient();
//webClient.Headers["Accept"] = "application/json";
//HttpResponseMessage response = await webClient.DownloadString("http://192.168.1.125:8866/api/savefile")



//HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create("http://localhost:18324/api/savefile");
//wReq.Method = "Post";
////wReq.ContentType = "application/json";
////wReq.ContentType = "application/x-www-form-urlencoded";
//wReq.ContentType = "application/json";

////byte[] data = Encoding.Default.GetBytes(HttpUtility.UrlEncode("key=rfwreewr2332322232&261=3&261=4"));

//var model = new DiskFileModel
//{
// FileName = "api测试文件123.txt",
// FileSaveName = "api测试文件save123.txt",
// FolderId = 6,
// UserId = 100001005,
// FileType = "文本",
// FileSize = 2345741,
// ExtendName = ".txt"
//};
//var json = JsonConvert.SerializeObject(model);
////byte[] data = Encoding.Default.GetBytes("{FileName:\"api测试文件123.txt\",FileSaveName:\"api测试文件save123\",FolderId:6,UserId:100001005,FileType:\"文本\",FileSize:23456,ExtendName:\".txt\"}");
//byte[] data = Encoding.Default.GetBytes(json);
//wReq.ContentLength = data.Length;
//Stream reqStream = wReq.GetRequestStream();
//reqStream.Write(data, 0, data.Length);
//reqStream.Close();
//using (StreamReader sr = new StreamReader(wReq.GetResponse().GetResponseStream()))
//{
// string result = sr.ReadToEnd();

// Console.WriteLine(result);
//}

//dooGet();
//var res = HttpGet("http://localhost:18324/api/GetResumFile?md5str=8806FE50830C364601F1CBDCF202EDE8.mp4&uid=100001005");
//Console.WriteLine(res);
Console.ReadKey();

//dooPost();


}

public static string HttpGet(string url)
{
//ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
Encoding encoding = Encoding.UTF8;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.Accept = "text/html, application/xhtml+xml, */*";
request.ContentType = "text/plain";

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
return reader.ReadToEnd();
}
}

/// <summary>
/// 获取url的返回值
/// </summary>
/// <param name="url">eg:http://m.weather.com.cn/atad/101010100.html </param>
public static string GetInfo(string url)
{
string strBuff = "";
Uri httpURL = new Uri(url);
///HttpWebRequest类继承于WebRequest,并没有自己的构造函数,需通过WebRequest的Creat方法 建立,并进行强制的类型转换
HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(httpURL);
///通过HttpWebRequest的GetResponse()方法建立HttpWebResponse,强制类型转换
HttpWebResponse httpResp = (HttpWebResponse)httpReq.GetResponse();
///GetResponseStream()方法获取HTTP响应的数据流,并尝试取得URL中所指定的网页内容
///若成功取得网页的内容,则以System.IO.Stream形式返回,若失败则产生ProtoclViolationException错 误。在此正确的做法应将以下的代码放到一个try块中处理。这里简单处理
Stream respStream = httpResp.GetResponseStream();
///返回的内容是Stream形式的,所以可以利用StreamReader类获取GetResponseStream的内容,并以
//StreamReader类的Read方法依次读取网页源程序代码每一行的内容,直至行尾(读取的编码格式:UTF8)
StreamReader respStreamReader = new StreamReader(respStream, Encoding.UTF8);
strBuff = respStreamReader.ReadToEnd();
return strBuff;
}

/// <summary>
/// HttpClient实现Get请求
/// </summary>
static async void dooGet()
{
string url = "http://192.168.1.125:8866/api/GetResumFile?md5str=8806FE50830C364601F1CBDCF202EDE8.mp4&uid=100001005";
//创建HttpClient(注意传入HttpClientHandler)
var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };

using (var http = new HttpClient(handler))
{
//await异步等待回应
var response = await http.GetAsync(url);
//确保HTTP成功状态值
response.EnsureSuccessStatusCode();
Console.WriteLine("112233");
//await异步读取最后的JSON(注意此时gzip已经被自动解压缩了,因为上面的AutomaticDecompression = DecompressionMethods.GZip)
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
}
}

/// <summary>
/// HttpClient实现Post请求
/// </summary>
static async void dooPost()
{
string url = "http://localhost:18324/api/savefile";
//var userId = "1";
//设置HttpClientHandler的AutomaticDecompression
var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
//创建HttpClient(注意传入HttpClientHandler)
using (var http = new HttpClient(handler))
{
//使用FormUrlEncodedContent做HttpContent
var content = new FormUrlEncodedContent(new Dictionary<string, string>()
{
{"FileName","api测试文件123.txt"},
{"FileSaveName","api测试文件save123.txt"},
{"FolderId","api测试文件123.txt"},
{"UserId","100001005"},
{"FileType","文本"},
{"FileSize","2345741"},
{"ExtendName",".txt"}}
);

//await异步等待回应
try
{
var response = await http.PostAsync(url, content);
//确保HTTP成功状态值
response.EnsureSuccessStatusCode();
//await异步读取最后的JSON(注意此时gzip已经被自动解压缩了,因为上面的AutomaticDecompression = DecompressionMethods.GZip)
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}

}

}

public static string HttpPost(string url, string body)
{

////ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
Encoding encoding = Encoding.UTF8;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.Accept = "text/html, application/xhtml+xml, */*";
request.ContentType = "application/json;charset=utf-8";

byte[] buffer = encoding.GetBytes(body);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
return reader.ReadToEnd();
}

//WebClient webClient = new WebClient();
//webClient.Headers["Accept"] = "application/json";

}
}

public class DiskFileModel
{
public string GuidId { get; set; }

/// <summary>
/// 文件名称
/// </summary>
public string FileName { get; set; }

/// <summary>
/// 文件名称
/// </summary>
public string FileSaveName { get; set; }

/// <summary>
/// 文件夹编号
/// </summary>
public int? FolderId { get; set; }

/// <summary>
///用户编号
/// </summary>
public int UserId { get; set; }

/// <summary>
/// 文件类型
/// </summary>
public string FileType { get; set; }

/// <summary>
/// 文件大小
/// </summary>
public int? FileSize { get; set; }

/// <summary>
/// 文件扩展名
/// </summary>
public string ExtendName { get; set; }

/// <summary>
/// 文件下载路径
/// </summary>
public string FileUrl { get; set; }

/// <summary>
/// 下载次数
/// </summary>
public int? DownloadCount { get; set; }

/// <summary>
/// 分享状态
/// </summary>
public int? ShareType { get; set; }

public bool? DeleteMark { get; set; }

public bool? IsEnabled { get; set; }

public string CreateUser { get; set; }

public DateTime? CreateTime { get; set; }

public string ModifyUser { get; set; }

public DateTime? ModifyTime { get; set; }

public string Remark { get; set; }
}
}

+ 36
- 0
ConsoleApp/Properties/AssemblyInfo.cs Datei anzeigen

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("ConsoleApp")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ConsoleApp")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]

// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("572742ef-632b-452e-9d47-3a81adbf55f5")]

// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

+ 4
- 0
ConsoleApp/packages.config Datei anzeigen

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="net452" />
</packages>

+ 72
- 0
GoChat.Controls/CommandBase.cs Datei anzeigen

@@ -0,0 +1,72 @@

using System;
using System.Windows.Input;

namespace GoChat.Controls
{
/// <summary>
/// Command基类,用于封装各种Command及执行
/// </summary>
public class CommandBase<T> : ICommand
{
#region 字段

private readonly Action<T> _executeHandler;
private readonly Func<T, bool> _canExecuteHandler;
public event EventHandler CanExecuteChanged;

#endregion

#region 构造函数

public CommandBase(Action<T> executeHandler)
: this(executeHandler, null)
{

}

public CommandBase(Action<T> executeHandler, Func<T, bool> canExecuteHandler)
{
_executeHandler = executeHandler;
_canExecuteHandler = canExecuteHandler;
}
#endregion
# region CommandBase成员

public bool OnCanExecute(T parameter)
{
if (_canExecuteHandler != null)
{
return _canExecuteHandler(parameter);
}
return true;
}

public void OnExecute(T parameter)
{
_executeHandler?.Invoke(parameter);
}
#endregion

# region ICommand成员
public void Execute(object parameter)
{
OnExecute((T)parameter);
}

public bool CanExecute(object parameter)
{
if (parameter == null && typeof(T).IsValueType)
{
return (_canExecuteHandler == null);
}

return OnCanExecute((T)parameter);
}


#endregion
}

}

+ 322
- 0
GoChat.Controls/ControlAttachProperty.cs Datei anzeigen

@@ -0,0 +1,322 @@
/*=====================================================================
*公司名称:
*功能描述:自定义附加属性
*创 建 者:高海波
*创建日期:2017/1/22 9:58:24
=====================================================================*/

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace GoChat.Controls
{
/// <summary>
/// 自定义附加属性
/// </summary>
public class ControlAttachProperty
{
#region Border圆角
/// <summary>
/// Border圆角
/// </summary>
public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.RegisterAttached(
"CornerRadius", typeof(CornerRadius), typeof(ControlAttachProperty), new PropertyMetadata(default(CornerRadius)));

public static void SetCornerRadius(DependencyObject element, CornerRadius value)
{
element.SetValue(CornerRadiusProperty, value);
}
public static CornerRadius GetCornerRadius(DependencyObject element)
{
return (CornerRadius)element.GetValue(CornerRadiusProperty);
}
#endregion

#region 标题颜色
public static readonly DependencyProperty TitleBrushProperty = DependencyProperty.RegisterAttached(
"TitleBrush", typeof(Brush), typeof(ControlAttachProperty), new PropertyMetadata(new SolidColorBrush(Colors.White)));

public static void SetTitleBrush(DependencyObject element, Brush value)
{
element.SetValue(TitleBrushProperty, value);
}

public static Brush GetTitleBrush(DependencyObject element)
{
return (Brush)element.GetValue(TitleBrushProperty);
}

#endregion

#region 标题栏圆角

/// <summary>
/// 标题栏圆角
/// </summary>
public static readonly DependencyProperty CaptionCornerRadiusProperty = DependencyProperty.RegisterAttached(
"CaptionCornerRadius", typeof(CornerRadius), typeof(ControlAttachProperty), new PropertyMetadata(default(CornerRadius)));

public static void SetCaptionCornerRadius(DependencyObject element, CornerRadius value)
{
element.SetValue(CaptionCornerRadiusProperty, value);
}

public static CornerRadius GetCaptionCornerRadius(DependencyObject element)
{
return (CornerRadius)element.GetValue(CaptionCornerRadiusProperty);
}

#endregion

#region 鼠标滑过border颜色
/// <summary>
/// 鼠标滑过border颜色
/// </summary>
public static readonly DependencyProperty MouseOverBorderBrushProperty = DependencyProperty.RegisterAttached(
"MouseOverBorderBrush", typeof(Brush), typeof(ControlAttachProperty), new PropertyMetadata(default(Brush)));

public static void SetMouseOverBorderBrush(DependencyObject element, Brush value)
{
element.SetValue(MouseOverBorderBrushProperty, value);
}

public static Brush GetMouseOverBorderBrush(DependencyObject element)
{
return (Brush)element.GetValue(MouseOverBorderBrushProperty);
}
#endregion

#region 水印
/// <summary>
/// 水印
/// </summary>
public static readonly DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached(
"Watermark", typeof(string), typeof(ControlAttachProperty), new PropertyMetadata(default(string)));

public static void SetWatermark(DependencyObject element, string value)
{
element.SetValue(WatermarkProperty, value);
}

public static string GetWatermark(DependencyObject element)
{
return (string)element.GetValue(WatermarkProperty);
}

#endregion

#region 水印前景色

/// <summary>
/// 水印前景色
/// </summary>
public static readonly DependencyProperty WatermarkForegroundProperty = DependencyProperty.RegisterAttached(
"WatermarkForeground", typeof(Brush), typeof(ControlAttachProperty), new PropertyMetadata(default(Brush)));

public static void SetWatermarkForeground(DependencyObject element, Brush value)
{
element.SetValue(WatermarkForegroundProperty, value);
}

public static Brush GetWatermarkForeground(DependencyObject element)
{
return (Brush)element.GetValue(WatermarkForegroundProperty);
}

#endregion

#region 水印Margin
/// <summary>
/// 水印Margin
/// </summary>
public static readonly DependencyProperty WatermarkMarginProperty = DependencyProperty.RegisterAttached(
"WatermarkMargin", typeof(Thickness), typeof(ControlAttachProperty), new PropertyMetadata(default(Thickness)));

public static void SetWatermarkMargin(DependencyObject element, Thickness value)
{
element.SetValue(WatermarkMarginProperty, value);
}

public static Thickness GetWatermarkMargin(DependencyObject element)
{
return (Thickness)element.GetValue(WatermarkMarginProperty);
}

#endregion

#region 字体图标大小

/// <summary>
/// 字体图标大小
/// </summary>
public static readonly DependencyProperty FontIconSizeProperty = DependencyProperty.RegisterAttached(
"FontIconSize", typeof(double), typeof(ControlAttachProperty), new PropertyMetadata(default(double)));

public static void SetFontIconSize(DependencyObject element, double value)
{
element.SetValue(FontIconSizeProperty, value);
}

public static double GetFontIconSize(DependencyObject element)
{
return (double)element.GetValue(FontIconSizeProperty);
}

#endregion

#region 字体图标前景色
/// <summary>
/// 字体图标前景色
/// </summary>
public static readonly DependencyProperty FontIconForegroundProperty = DependencyProperty.RegisterAttached(
"FontIconForeground", typeof(Brush), typeof(ControlAttachProperty), new PropertyMetadata(default(Brush)));

public static void SetFontIconForeground(DependencyObject element, Brush value)
{
element.SetValue(FontIconForegroundProperty, value);
}

public static Brush GetFontIconForeground(DependencyObject element)
{
return (Brush)element.GetValue(FontIconForegroundProperty);
}
#endregion

#region 字体图标Margin

public static readonly DependencyProperty FontIconMarginProperty = DependencyProperty.RegisterAttached(
"FontIconMargin", typeof(Thickness), typeof(ControlAttachProperty), new PropertyMetadata(default(Thickness)));

public static void SetFontIconMargin(DependencyObject element, Thickness value)
{
element.SetValue(FontIconMarginProperty, value);
}

public static Thickness GetFontIconMargin(DependencyObject element)
{
return (Thickness)element.GetValue(FontIconMarginProperty);
}

#endregion

#region 字体图标Unicode编码
/// <summary>
/// 字体图标Unicode编码
/// </summary>
public static readonly DependencyProperty FontIconValueProperty = DependencyProperty.RegisterAttached(
"FontIconValue", typeof(string), typeof(ControlAttachProperty), new PropertyMetadata(default(string)));

public static void SetFontIconValue(DependencyObject element, string value)
{
element.SetValue(FontIconValueProperty, value);
}

public static string GetFontIconValue(DependencyObject element)
{
return (string)element.GetValue(FontIconValueProperty);
}

#endregion

#region 是否显示字体图标
/// <summary>
/// 是否显示字体图标
/// 默认false
/// </summary>
public static readonly DependencyProperty IsShowFontIconProperty = DependencyProperty.RegisterAttached(
"IsShowFontIcon", typeof(bool), typeof(ControlAttachProperty), new PropertyMetadata(false));

public static void SetIsShowFontIcon(DependencyObject element, bool value)
{
element.SetValue(IsShowFontIconProperty, value);
}

public static bool GetIsShowFontIcon(DependencyObject element)
{
return (bool)element.GetValue(IsShowFontIconProperty);
}

#endregion

#region 附件内容
/// <summary>
/// 附件内容
/// </summary>
public static readonly DependencyProperty AttachContentProperty = DependencyProperty.RegisterAttached(
"AttachContent", typeof(ControlTemplate), typeof(ControlAttachProperty), new PropertyMetadata(default(ControlTemplate)));

public static void SetAttachContent(DependencyObject element, ControlTemplate value)
{
element.SetValue(AttachContentProperty, value);
}

public static ControlTemplate GetAttachContent(DependencyObject element)
{
return (ControlTemplate)element.GetValue(AttachContentProperty);
}

#endregion

#region 鼠标进入背景色
/// <summary>
/// 鼠标进入背景色
/// </summary>
public static readonly DependencyProperty MouseOverBackgroundProperty = DependencyProperty.RegisterAttached(
"MouseOverBackground", typeof(Brush), typeof(ControlAttachProperty), new PropertyMetadata(default(Brush)));

public static void SetMouseOverBackground(DependencyObject element, Brush value)
{
element.SetValue(MouseOverBackgroundProperty, value);
}

public static Brush GetMouseOverBackground(DependencyObject element)
{
return (Brush)element.GetValue(MouseOverBackgroundProperty);
}

#endregion

public static readonly DependencyProperty FontIconMouseOverGroundProperty = DependencyProperty.RegisterAttached(
"FontIconMouseOverGround", typeof (Brush), typeof (ControlAttachProperty), new PropertyMetadata(default(Brush)));

public static void SetFontIconMouseOverGround(DependencyObject element, Brush value)
{
element.SetValue(FontIconMouseOverGroundProperty, value);
}

public static Brush GetFontIconMouseOverGround(DependencyObject element)
{
return (Brush) element.GetValue(FontIconMouseOverGroundProperty);
}

/// <summary>
/// 是否正在加载数据
/// </summary>
public static readonly DependencyProperty IsBusyProperty = DependencyProperty.RegisterAttached(
"IsBusy", typeof(bool), typeof(ControlAttachProperty), new PropertyMetadata(default(bool)));

public static void SetIsBusy(DependencyObject element, bool value)
{
element.SetValue(IsBusyProperty, value);
}

public static bool GetIsBusy(DependencyObject element)
{
return (bool) element.GetValue(IsBusyProperty);
}

public static readonly DependencyProperty IsEmptyProperty = DependencyProperty.RegisterAttached(
"IsEmpty", typeof(bool), typeof(ControlAttachProperty), new PropertyMetadata(default(bool)));

public static void SetIsEmpty(DependencyObject element, bool value)
{
element.SetValue(IsEmptyProperty, value);
}

public static bool GetIsEmpty(DependencyObject element)
{
return (bool) element.GetValue(IsEmptyProperty);
}
}
}

+ 24
- 0
GoChat.Controls/ExCommandParameter.cs Datei anzeigen

@@ -0,0 +1,24 @@
using System;
using System.Windows;

namespace GoChat.Controls
{
/// <summary>
/// CommandParameter扩展
/// </summary>
public class ExCommandParameter
{
/// <summary>
/// 事件触发源
/// </summary>
public DependencyObject Sender { get; set; }
/// <summary>
/// 事件参数
/// </summary>
public EventArgs EventArgs { get; set; }
/// <summary>
/// 额外参数
/// </summary>
public object Parameter { get; set; }
}
}

+ 134
- 0
GoChat.Controls/ExInvokeCommandAction.cs Datei anzeigen

@@ -0,0 +1,134 @@
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace GoChat.Controls
{
/// <summary>
/// 扩展的InvokeCommandAction
/// </summary>
public class ExInvokeCommandAction : TriggerAction<DependencyObject>
{

private string _commandName;
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(ExInvokeCommandAction), null);
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(ExInvokeCommandAction), null);
/// <summary>
/// 获得或设置此操作应调用的命令的名称。
/// </summary>
/// <value>此操作应调用的命令的名称。</value>
/// <remarks>如果设置了此属性和 Command 属性,则此属性将被后者所取代。</remarks>
public string CommandName
{
get
{
base.ReadPreamble();
return this._commandName;
}
set
{
if (this.CommandName != value)
{
base.WritePreamble();
this._commandName = value;
base.WritePostscript();
}
}
}
/// <summary>
/// 获取或设置此操作应调用的命令。这是依赖属性。
/// </summary>
/// <value>要执行的命令。</value>
/// <remarks>如果设置了此属性和 CommandName 属性,则此属性将优先于后者。</remarks>
public ICommand Command
{
get
{
return (ICommand)base.GetValue(ExInvokeCommandAction.CommandProperty);
}
set
{
base.SetValue(ExInvokeCommandAction.CommandProperty, value);
}
}
/// <summary>
/// 获得或设置命令参数。这是依赖属性。
/// </summary>
/// <value>命令参数。</value>
/// <remarks>这是传递给 ICommand.CanExecute 和 ICommand.Execute 的值。</remarks>
public object CommandParameter
{
get
{
return base.GetValue(ExInvokeCommandAction.CommandParameterProperty);
}
set
{
base.SetValue(ExInvokeCommandAction.CommandParameterProperty, value);
}
}
/// <summary>
/// 调用操作。
/// </summary>
/// <param name="parameter">操作的参数。如果操作不需要参数,则可以将参数设置为空引用。</param>
protected override void Invoke(object parameter)
{
if (base.AssociatedObject != null)
{
ICommand command = this.ResolveCommand();

/*
* ★★★★★★★★★★★★★★★★★★★★★★★★
* 注意这里添加了事件触发源和事件参数
* ★★★★★★★★★★★★★★★★★★★★★★★★
*/
var exParameter = new ExCommandParameter
{
Sender = AssociatedObject,
Parameter = GetValue(CommandParameterProperty),
EventArgs = parameter as EventArgs,
};

if (command != null && command.CanExecute(exParameter))
{
/*
* ★★★★★★★★★★★★★★★★★★★★★★★★
* 注意将扩展的参数传递到Execute方法中
* ★★★★★★★★★★★★★★★★★★★★★★★★
*/
command.Execute(exParameter);
}
}
}
private ICommand ResolveCommand()
{
ICommand result = null;
if (this.Command != null)
{
result = this.Command;
}
else
{
if (base.AssociatedObject != null)
{
Type type = AssociatedObject.GetType();
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
PropertyInfo[] array = properties;
foreach (PropertyInfo propertyInfo in array)
{
if (typeof(ICommand).IsAssignableFrom(propertyInfo.PropertyType) && string.Equals(propertyInfo.Name, this.CommandName, StringComparison.Ordinal))
{
result = (ICommand)propertyInfo.GetValue(base.AssociatedObject, null);
}
}
}
}
return result;
}

}
}



+ 208
- 0
GoChat.Controls/GoChat.Controls.csproj Datei anzeigen

@@ -0,0 +1,208 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{113E8C2F-446C-44A6-9F30-A794CA483846}</ProjectGuid>
<OutputType>library</OutputType>
<RootNamespace>GoChat.Controls</RootNamespace>
<AssemblyName>GoChat.Controls</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<SccProjectName>GoChat.Controls</SccProjectName>
<SccLocalPath>1~a7250b02-76e9-4d74-aa27-f5cdf7719296</SccLocalPath>
<SccAuxPath>http://123.57.209.16:8090/VaultService</SccAuxPath>
<SccProvider>SourceGear Vault Visual Studio 2005 Client:{1EA47954-8515-402d-82D9-B5C332120A8D}</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Expression.Interactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MicrosoftExpressionInteractions.3.0.40218.0\lib\net45\Microsoft.Expression.Interactions.dll</HintPath>
</Reference>
<Reference Include="PresentationFramework.Aero" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\System.Windows.Interactivity.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="XamlAnimatedGif, Version=1.1.10.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\XamlAnimatedGif.1.1.10\lib\net45\XamlAnimatedGif.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Page Include="Themes\FontIcon.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\Generic.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatBulletCheckBox.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatButton.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatComboBox.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatListBox.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatMenu.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatPasswordBox.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatRichTextBox.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatScrollViewer.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatTabControl.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatTabItem.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatTextBox.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatToggleButton.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatToolTip.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatTreeView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\GoChatWin.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\PromptChrome.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="CommandBase.cs" />
<Compile Include="ControlAttachProperty.cs" />
<Compile Include="ExCommandParameter.cs" />
<Compile Include="ExInvokeCommandAction.cs" />
<Compile Include="GoChatButton.cs" />
<Compile Include="GoChatTabControl.cs" />
<Compile Include="GoChatTabItem.cs" />
<Compile Include="GoChatTextBox.cs" />
<Compile Include="GoChatWin.cs" />
<Compile Include="PasswordBoxHelper.cs" />
<Compile Include="PasswordBoxWaterMark.cs" />
<Compile Include="PromptAdorner.cs" />
<Compile Include="PromptChrome.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="Themes\GoChatBulletCheckBox.xaml.cs">
<DependentUpon>GoChatBulletCheckBox.xaml</DependentUpon>
</Compile>
<Compile Include="WinStateBehavior.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Resource Include="Resources\fontawesome\FontAwesome.otf" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\fontawesome\1.png" />
<Resource Include="Resources\fontawesome\2.png" />
<Resource Include="Resources\fontawesome\3.png" />
<Resource Include="Resources\fontawesome\4.png" />
<Resource Include="Resources\fontawesome\5.png" />
<Resource Include="Resources\Images\01.png" />
<Resource Include="Resources\Images\02.png" />
<Resource Include="Resources\Images\03.png" />
<Resource Include="Resources\Images\mie.png" />
<Resource Include="Resources\Images\mim.png" />
<Resource Include="Resources\Images\min.png" />
<Resource Include="Resources\Images\mme.png" />
<Resource Include="Resources\Images\mmm.png" />
<Resource Include="Resources\Images\mmn.png" />
<Resource Include="Resources\Images\mxe.png" />
<Resource Include="Resources\Images\mxm.png" />
<Resource Include="Resources\Images\mxn.png" />
<Resource Include="Resources\Images\ske.png" />
<Resource Include="Resources\Images\skm.png" />
<Resource Include="Resources\Images\skn.png" />
<Resource Include="Resources\Images\xe.png" />
<Resource Include="Resources\Images\xm.png" />
<Resource Include="Resources\Images\xn.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

+ 182
- 0
GoChat.Controls/GoChatButton.cs Datei anzeigen

@@ -0,0 +1,182 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace GoChat.Controls
{
/// <summary>
/// 自定义按钮
/// </summary>
public class GoChatButton : Button
{
static GoChatButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GoChatButton), new FrameworkPropertyMetadata(typeof(GoChatButton)));
}

public static readonly DependencyProperty FontIconValueProperty = DependencyProperty.Register(
"FontIconValue", typeof(string), typeof(GoChatButton), new PropertyMetadata(default(string)));

/// <summary>
/// 字体图标Unicode编码
/// </summary>
public string FontIconValue
{
get { return (string)GetValue(FontIconValueProperty); }
set { SetValue(FontIconValueProperty, value); }
}

public static readonly DependencyProperty FontIconSizeProperty = DependencyProperty.Register(
"FontIconSize", typeof(double), typeof(GoChatButton), new PropertyMetadata(default(double)));
/// <summary>
/// 字体图标大小
/// </summary>
public double FontIconSize
{
get { return (double)GetValue(FontIconSizeProperty); }
set { SetValue(FontIconSizeProperty, value); }
}

public static readonly DependencyProperty FontIconMarginProperty = DependencyProperty.Register(
"FontIconMargin", typeof(Thickness), typeof(GoChatButton), new PropertyMetadata(default(Thickness)));
/// <summary>
/// 字体图标间距
/// </summary>
public Thickness FontIconMargin
{
get { return (Thickness)GetValue(FontIconMarginProperty); }
set { SetValue(FontIconMarginProperty, value); }
}


public static readonly DependencyProperty MouseOverBackgroundProperty = DependencyProperty.Register(
"MouseOverBackground", typeof(Brush), typeof(GoChatButton), new PropertyMetadata(default(Brush)));
/// <summary>
/// 鼠标进入背景样式
/// </summary>
public Brush MouseOverBackground
{
get { return (Brush)GetValue(MouseOverBackgroundProperty); }
set { SetValue(MouseOverBackgroundProperty, value); }
}

public static readonly DependencyProperty MouseOverForeGroundProperty = DependencyProperty.Register(
"MouseOverForeGround", typeof(Brush), typeof(GoChatButton), new PropertyMetadata(default(Brush)));
/// <summary>
/// 鼠标进入前景样式
/// </summary>
public Brush MouseOverForeGround
{
get { return (Brush)GetValue(MouseOverForeGroundProperty); }
set { SetValue(MouseOverForeGroundProperty, value); }
}

public static readonly DependencyProperty PressBackGroundProperty = DependencyProperty.Register(
"PressBackGround", typeof(Brush), typeof(GoChatButton), new PropertyMetadata(default(Brush)));
/// <summary>
/// 鼠标按下背景样式
/// </summary>
public Brush PressBackGround
{
get { return (Brush)GetValue(PressBackGroundProperty); }
set { SetValue(PressBackGroundProperty, value); }
}

public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(
"CornerRadius", typeof(CornerRadius), typeof(GoChatButton), new PropertyMetadata(default(CornerRadius)));
/// <summary>
/// 按钮圆角大小,左上,右上,右下,左下
/// </summary>
public CornerRadius CornerRadius
{
get { return (CornerRadius)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}

public static readonly DependencyProperty ContentOrientationProperty = DependencyProperty.Register(
"ContentOrientation", typeof(Orientation), typeof(GoChatButton), new PropertyMetadata(default(Orientation)));
/// <summary>
/// 内容排列方式(水平、垂直)
/// </summary>
public Orientation ContentOrientation
{
get { return (Orientation)GetValue(ContentOrientationProperty); }
set { SetValue(ContentOrientationProperty, value); }
}

public static readonly DependencyProperty IsOpenAnimationProperty = DependencyProperty.Register(
"IsOpenAnimation", typeof(bool), typeof(GoChatButton), new PropertyMetadata(default(bool)));
/// <summary>
/// 是否开启动画效果
/// </summary>
public bool IsOpenAnimation
{
get { return (bool)GetValue(IsOpenAnimationProperty); }
set { SetValue(IsOpenAnimationProperty, value); }
}

public static readonly DependencyProperty IsShowTextProperty = DependencyProperty.Register(
"IsShowText", typeof(bool), typeof(GoChatButton), new PropertyMetadata(default(bool)));
/// <summary>
/// 是否显示按钮文字
/// </summary>
public bool IsShowText
{
get { return (bool)GetValue(IsShowTextProperty); }
set { SetValue(IsShowTextProperty, value); }
}

public static readonly DependencyProperty EllipseFillBrushProperty = DependencyProperty.Register(
"EllipseFillBrush", typeof(Brush), typeof(GoChatButton), new PropertyMetadata(default(Brush)));
/// <summary>
/// 环形按钮填充
/// </summary>
public Brush EllipseFillBrush
{
get { return (Brush)GetValue(EllipseFillBrushProperty); }
set { SetValue(EllipseFillBrushProperty, value); }
}

public static readonly DependencyProperty EllipseStrokeThicknessProperty = DependencyProperty.Register(
"EllipseStrokeThickness", typeof(double), typeof(GoChatButton), new PropertyMetadata(default(double)));
/// <summary>
/// 环形图边框宽度
/// </summary>
public double EllipseStrokeThickness
{
get { return (double)GetValue(EllipseStrokeThicknessProperty); }
set { SetValue(EllipseStrokeThicknessProperty, value); }
}

public static readonly DependencyProperty EllipseHeightAndWidthProperty = DependencyProperty.Register(
"EllipseHeightAndWidth", typeof (double), typeof (GoChatButton), new PropertyMetadata(default(double)));
/// <summary>
/// 环形图大小
/// </summary>
public double EllipseHeightAndWidth
{
get { return (double) GetValue(EllipseHeightAndWidthProperty); }
set { SetValue(EllipseHeightAndWidthProperty, value); }
}

public static readonly DependencyProperty EllipseStrokeProperty = DependencyProperty.Register(
"EllipseStroke", typeof (Brush), typeof (GoChatButton), new PropertyMetadata(default(Brush)));
/// <summary>
/// 环形图边框颜色
/// </summary>
public Brush EllipseStroke
{
get { return (Brush) GetValue(EllipseStrokeProperty); }
set { SetValue(EllipseStrokeProperty, value); }
}

public static readonly DependencyProperty TextPaddingProperty = DependencyProperty.Register(
"TextPadding", typeof(Thickness), typeof(GoChatButton), new PropertyMetadata(default(Thickness)));

public Thickness TextPadding
{
get { return (Thickness) GetValue(TextPaddingProperty); }
set { SetValue(TextPaddingProperty, value); }
}
}
}

+ 25
- 0
GoChat.Controls/GoChatTabControl.cs Datei anzeigen

@@ -0,0 +1,25 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace GoChat.Controls
{
public class GoChatTabControl : TabControl
{
static GoChatTabControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GoChatTabControl), new FrameworkPropertyMetadata(typeof(GoChatTabControl)));
}

public static readonly DependencyProperty HeaderPanelBackgroundProperty = DependencyProperty.Register(
"HeaderPanelBackground", typeof (Brush), typeof (GoChatTabControl), new PropertyMetadata(default(Brush)));
/// <summary>
/// 选项面板背景色
/// </summary>
public Brush HeaderPanelBackground
{
get { return (Brush) GetValue(HeaderPanelBackgroundProperty); }
set { SetValue(HeaderPanelBackgroundProperty, value); }
}
}
}

+ 44
- 0
GoChat.Controls/GoChatTabItem.cs Datei anzeigen

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace GoChat.Controls
{
public class GoChatTabItem : TabItem
{
static GoChatTabItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GoChatTabItem), new FrameworkPropertyMetadata(typeof(GoChatTabItem)));
}

public static readonly DependencyProperty TabItemHorizontalAlignmentProperty = DependencyProperty.Register(
"TabItemHorizontalAlignment", typeof (HorizontalAlignment), typeof (GoChatTabItem), new PropertyMetadata(default(HorizontalAlignment)));

public HorizontalAlignment TabItemHorizontalAlignment
{
get { return (HorizontalAlignment) GetValue(TabItemHorizontalAlignmentProperty); }
set { SetValue(TabItemHorizontalAlignmentProperty, value); }
}

public static readonly DependencyProperty SelectedColorBrushProperty = DependencyProperty.Register(
"SelectedColorBrush", typeof (Brush), typeof (GoChatTabItem), new PropertyMetadata(default(Brush)));

public Brush SelectedColorBrush
{
get { return (Brush) GetValue(SelectedColorBrushProperty); }
set { SetValue(SelectedColorBrushProperty, value); }
}
}
}

+ 44
- 0
GoChat.Controls/GoChatTextBox.cs Datei anzeigen

@@ -0,0 +1,44 @@
/*=====================================================================
*公司名称:
*功能描述:文本框、密码框控件
*创 建 者:高海波
*创建日期:2017/2/15 9:18:27
=====================================================================*/
using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace GoChat.Controls
{
/// <summary>
/// 文本框控件
/// </summary>
public class GoChatTextBox : TextBox
{
static GoChatTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GoChatTextBox), new FrameworkPropertyMetadata(typeof(GoChatTextBox)));
}
public static readonly DependencyProperty FontIconHorizontalAlignmentProperty = DependencyProperty.Register(
"FontIconHorizontalAlignment", typeof (HorizontalAlignment), typeof (GoChatTextBox), new PropertyMetadata(default(HorizontalAlignment)));

public HorizontalAlignment FontIconHorizontalAlignment
{
get { return (HorizontalAlignment) GetValue(FontIconHorizontalAlignmentProperty); }
set { SetValue(FontIconHorizontalAlignmentProperty, value); }
}

public static readonly DependencyProperty FontIconMouseOverForegroundProperty = DependencyProperty.Register(
"FontIconMouseOverForeground", typeof (Brush), typeof (GoChatTextBox), new PropertyMetadata(default(Brush)));

public Brush FontIconMouseOverForeground
{
get { return (Brush) GetValue(FontIconMouseOverForegroundProperty); }
set { SetValue(FontIconMouseOverForegroundProperty, value); }
}
}
}

+ 311
- 0
GoChat.Controls/GoChatWin.cs Datei anzeigen

@@ -0,0 +1,311 @@
/*=====================================================================
*公司名称:
*功能描述:自定义窗体
*创 建 者:高海波
*创建日期:2017/1/23 15:28:51
=====================================================================*/

using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace GoChat.Controls
{
/// <summary>
/// 自定义窗体
/// </summary>
public class GoChatWin : Window
{
bool _isWiden;
public CommandBase<ExCommandParameter> MouseLeftButtonDownCommand { get; set; }
public CommandBase<ExCommandParameter> MouseLeftButtonUpCommand { get; set; }
public CommandBase<ExCommandParameter> MouseMoveCommand { get; set; }
public GoChatWin()
{
WindowStartupLocation = WindowStartupLocation.CenterScreen;
MouseLeftButtonDown += GoChatWin_MouseLeftButtonDown;
MouseLeftButtonDownCommand = new CommandBase<ExCommandParameter>(MouseLeftButtonDown_Execute);
MouseLeftButtonUpCommand = new CommandBase<ExCommandParameter>(MouseLeftButtonUp_Execute);
MouseMoveCommand = new CommandBase<ExCommandParameter>(MouseMoveCommand_Execute);
MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;
MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
}
private void MouseLeftButtonDown_Execute(ExCommandParameter e)
{
_isWiden = true;
}
private void MouseLeftButtonUp_Execute(ExCommandParameter e)
{
_isWiden = false;

Rectangle rect = (Rectangle)e.Sender;
rect.ReleaseMouseCapture();
}
private void MouseMoveCommand_Execute(ExCommandParameter e)
{
var fx = e.Parameter.ToString();
var arg = e.EventArgs as MouseEventArgs;
Rectangle rect = (Rectangle)e.Sender;
if (_isWiden)
{
rect.CaptureMouse();
if (fx=="zy")
{
double newWidth = arg.GetPosition(this).X + 5;
if (newWidth > 0) Width = newWidth;
}
else
{
double newHight = arg.GetPosition(this).Y + 5;
if (newHight > 0) Height = newHight;
}
}
}
void GoChatWin_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (!_isWiden&&e.ButtonState == MouseButtonState.Pressed)
{
//if (sender != e.Source)
//{
// e.Handled = true;
//}
//else
//{
// this.DragMove();
//}
DragMove();

}
}
static GoChatWin()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GoChatWin), new FrameworkPropertyMetadata(typeof(GoChatWin)));
}

public static readonly DependencyProperty CaptionCornerRadiusProperty = DependencyProperty.Register(
"CaptionCornerRadius", typeof (CornerRadius), typeof (GoChatWin), new PropertyMetadata(default(CornerRadius)));

public CornerRadius CaptionCornerRadius
{
get { return (CornerRadius) GetValue(CaptionCornerRadiusProperty); }
set { SetValue(CaptionCornerRadiusProperty, value); }
}
public static readonly DependencyProperty CaptionHeightProperty = DependencyProperty.Register(
"CaptionHeight", typeof(double), typeof(GoChatWin), new PropertyMetadata(22d));
/// <summary>
/// 标题栏高度
/// 默认为22d
/// </summary>
public double CaptionHeight
{
get { return (double)GetValue(CaptionHeightProperty); }
set { SetValue(CaptionHeightProperty, value); }
}

public static readonly DependencyProperty CaptionBackGroundProperty = DependencyProperty.Register(
"CaptionBackGround", typeof(Brush), typeof(GoChatWin), new PropertyMetadata(new BrushConverter().ConvertFrom("#1a90d5")));
/// <summary>
/// 标题栏背景色
/// </summary>
public Brush CaptionBackGround
{
get { return (Brush)GetValue(CaptionBackGroundProperty); }
set { SetValue(CaptionBackGroundProperty, value); }
}

public static readonly DependencyProperty CaptionForegroundProperty = DependencyProperty.Register(
"CaptionForeground", typeof(Brush), typeof(GoChatWin), new PropertyMetadata(default(Brush)));
/// <summary>
/// 标题栏前景色
/// </summary>
public Brush CaptionForeground
{
get { return (Brush)GetValue(CaptionForegroundProperty); }
set { SetValue(CaptionForegroundProperty, value); }
}

public static readonly DependencyProperty MaxIsEnableProperty = DependencyProperty.Register(
"MaxIsEnable", typeof(bool), typeof(GoChatWin), new PropertyMetadata(false));
/// <summary>
/// 窗体最大化按钮是否可用
/// </summary>
public bool MaxIsEnable
{
get { return (bool)GetValue(MaxIsEnableProperty); }
set { SetValue(MaxIsEnableProperty, value); }
}

public static readonly DependencyProperty MinIsEnableProperty = DependencyProperty.Register(
"MinIsEnable", typeof(bool), typeof(GoChatWin), new PropertyMetadata(true));
/// <summary>
/// 窗体最小化按钮是否可用
/// 默认为true
/// </summary>
public bool MinIsEnable
{
get { return (bool)GetValue(MinIsEnableProperty); }
set { SetValue(MinIsEnableProperty, value); }
}

public static readonly DependencyProperty CloseIsEnableProperty = DependencyProperty.Register(
"CloseIsEnable", typeof(bool), typeof(GoChatWin), new PropertyMetadata(true));
/// <summary>
/// 窗体关闭按钮是否可用
/// 默认为true
/// </summary>
public bool CloseIsEnable
{
get { return (bool)GetValue(CloseIsEnableProperty); }
set { SetValue(CloseIsEnableProperty, value); }
}

public static readonly DependencyProperty IsShowTitleProperty = DependencyProperty.Register(
"IsShowTitle", typeof(bool), typeof(GoChatWin), new PropertyMetadata(false));
/// <summary>
/// 是否显示标题
/// </summary>
public bool IsShowTitle
{
get { return (bool)GetValue(IsShowTitleProperty); }
set { SetValue(IsShowTitleProperty, value); }
}

public bool IsShowTitleImage { get; set; }

public static readonly DependencyProperty TitleImageSourceProperty = DependencyProperty.Register(
"TitleImageSource", typeof (ImageSource), typeof (GoChatWin), new PropertyMetadata(default(ImageSource)));

public ImageSource TitleImageSource
{
get { return (ImageSource) GetValue(TitleImageSourceProperty); }
set { SetValue(TitleImageSourceProperty, value); }
}

public static readonly DependencyProperty TitleImageHeightProperty = DependencyProperty.Register(
"TitleImageHeight", typeof(double), typeof(GoChatWin), new PropertyMetadata(default(double)));

public double TitleImageHeight
{
get { return (double) GetValue(TitleImageHeightProperty); }
set { SetValue(TitleImageHeightProperty, value); }
}

public static readonly DependencyProperty TitleImageWidthProperty = DependencyProperty.Register(
"TitleImageWidth", typeof(double), typeof(GoChatWin), new PropertyMetadata(default(double)));

public double TitleImageWidth
{
get { return (double) GetValue(TitleImageWidthProperty); }
set { SetValue(TitleImageWidthProperty, value); }
}

public static readonly DependencyProperty IsShowBackGroundEffetProperty = DependencyProperty.Register(
"IsShowBackGroundEffet", typeof (bool), typeof (GoChatWin), new PropertyMetadata(true));
/// <summary>
/// 是否显示背景遮罩效果
/// 默认为true
/// </summary>
public bool IsShowBackGroundEffet
{
get { return (bool) GetValue(IsShowBackGroundEffetProperty); }
set { SetValue(IsShowBackGroundEffetProperty, value); }
}

public static readonly DependencyProperty IsShowOpenLinearGradientProperty = DependencyProperty.Register(
"IsShowOpenLinearGradient", typeof (bool), typeof (GoChatWin), new PropertyMetadata(default(bool)));
/// <summary>
/// 窗体展示时是否启用渐变效果
/// </summary>
public bool IsShowOpenLinearGradient
{
get { return (bool) GetValue(IsShowOpenLinearGradientProperty); }
set { SetValue(IsShowOpenLinearGradientProperty, value); }
}

public static readonly DependencyProperty TitleIsSupportChangeWindowStateProperty = DependencyProperty.Register(
"TitleIsSupportChangeWindowState", typeof (bool), typeof (GoChatWin), new PropertyMetadata(default(bool)));
/// <summary>
/// 标题是否支持改变窗体状态
/// </summary>
public bool TitleIsSupportChangeWindowState
{
get { return (bool) GetValue(TitleIsSupportChangeWindowStateProperty); }
set { SetValue(TitleIsSupportChangeWindowStateProperty, value); }
}

public static readonly DependencyProperty IsGifBackgroundProperty = DependencyProperty.Register(
"IsGifBackground", typeof (bool), typeof (GoChatWin), new PropertyMetadata(default(bool)));

/// <summary>
/// 是否是动态背景
/// </summary>
public bool IsGifBackground
{
get { return (bool) GetValue(IsGifBackgroundProperty); }
set { SetValue(IsGifBackgroundProperty, value); }
}

public static readonly DependencyProperty GifSourceUriProperty = DependencyProperty.Register(
"GifSourceUri", typeof(Uri), typeof(GoChatWin), new PropertyMetadata(default(Uri)));
/// <summary>
/// 动态背景地址
/// </summary>
public Uri GifSourceUri
{
get { return (Uri) GetValue(GifSourceUriProperty); }
set { SetValue(GifSourceUriProperty, value); }
}

public static readonly DependencyProperty BarnerBrushProperty = DependencyProperty.Register(
"BarnerBrush", typeof(Brush), typeof(GoChatWin), new PropertyMetadata(new SolidColorBrush(ChangeColor(Color.FromArgb(Convert.ToByte(255), Convert.ToByte(26), Convert.ToByte(144), Convert.ToByte(213)), 0.3f))));

/// <summary>
/// Barner颜色
/// </summary>
public Brush BarnerBrush
{
get { return (Brush)GetValue(BarnerBrushProperty); }
set { SetValue(BarnerBrushProperty, value); }
}

static Color ChangeColor(Color color, float correctionFactor)
{
float red = (float)color.R;
float green = (float)color.G;
float blue = (float)color.B;

if (correctionFactor < 0)
{
correctionFactor = 1 + correctionFactor;
red *= correctionFactor;
green *= correctionFactor;
blue *= correctionFactor;
}
else
{
red = (255 - red) * correctionFactor + red;
green = (255 - green) * correctionFactor + green;
blue = (255 - blue) * correctionFactor + blue;
}

if (red < 0) red = 0;

if (red > 255) red = 255;

if (green < 0) green = 0;

if (green > 255) green = 255;

if (blue < 0) blue = 0;

if (blue > 255) blue = 255;

return Color.FromArgb(color.A, (byte)red, (byte)green, (byte)blue);
}
}
}

+ 80
- 0
GoChat.Controls/PasswordBoxHelper.cs Datei anzeigen

@@ -0,0 +1,80 @@
using System.Windows;
using System.Windows.Controls;

namespace GoChat.Controls
{
/// <summary>
/// 为PasswordBox控件的Password增加绑定功能
/// </summary>
public static class PasswordBoxHelper
{
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.RegisterAttached("Password",
typeof(string), typeof(PasswordBoxHelper),
new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged));
public static readonly DependencyProperty AttachProperty =
DependencyProperty.RegisterAttached("Attach",
typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false, Attach));
private static readonly DependencyProperty IsUpdatingProperty =
DependencyProperty.RegisterAttached("IsUpdating", typeof(bool),
typeof(PasswordBoxHelper));

public static void SetAttach(DependencyObject dp, bool value)
{
dp.SetValue(AttachProperty, value);
}
public static bool GetAttach(DependencyObject dp)
{
return (bool)dp.GetValue(AttachProperty);
}
public static string GetPassword(DependencyObject dp)
{
return (string)dp.GetValue(PasswordProperty);
}
public static void SetPassword(DependencyObject dp, string value)
{
dp.SetValue(PasswordProperty, value);
}
private static bool GetIsUpdating(DependencyObject dp)
{
return (bool)dp.GetValue(IsUpdatingProperty);
}
private static void SetIsUpdating(DependencyObject dp, bool value)
{
dp.SetValue(IsUpdatingProperty, value);
}
private static void OnPasswordPropertyChanged(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
passwordBox.PasswordChanged -= PasswordChanged;
if (!(bool)GetIsUpdating(passwordBox))
{
passwordBox.Password = (string)e.NewValue;
}
passwordBox.PasswordChanged += PasswordChanged;
}
private static void Attach(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
if (passwordBox == null)
return;
if ((bool)e.OldValue)
{
passwordBox.PasswordChanged -= PasswordChanged;
}
if ((bool)e.NewValue)
{
passwordBox.PasswordChanged += PasswordChanged;
}
}
private static void PasswordChanged(object sender, RoutedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
SetIsUpdating(passwordBox, true);
SetPassword(passwordBox, passwordBox.Password);
SetIsUpdating(passwordBox, false);
}
}
}

+ 66
- 0
GoChat.Controls/PasswordBoxWaterMark.cs Datei anzeigen

@@ -0,0 +1,66 @@
using System.Windows;
using System.Windows.Controls;

namespace GoChat.Controls
{
/// <summary>
/// PasswordBox添加水印辅助类
/// </summary>
public class PasswordBoxWaterMark : DependencyObject
{
public static bool GetIsMonitoring(DependencyObject obj)
{
return (bool)obj.GetValue(IsMonitoringProperty);
}

public static void SetIsMonitoring(DependencyObject obj, bool value)
{
obj.SetValue(IsMonitoringProperty, value);
}

public static readonly DependencyProperty IsMonitoringProperty =
DependencyProperty.RegisterAttached("IsMonitoring", typeof(bool), typeof(PasswordBoxWaterMark), new UIPropertyMetadata(false, OnIsMonitoringChanged));



public static int GetPasswordLength(DependencyObject obj)
{
return (int)obj.GetValue(PasswordLengthProperty);
}

public static void SetPasswordLength(DependencyObject obj, int value)
{
obj.SetValue(PasswordLengthProperty, value);
}

public static readonly DependencyProperty PasswordLengthProperty =
DependencyProperty.RegisterAttached("PasswordLength", typeof(int), typeof(PasswordBoxWaterMark), new UIPropertyMetadata(0));

private static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var pb = d as PasswordBox;
if (pb == null)
{
return;
}
if ((bool)e.NewValue)
{
pb.PasswordChanged += PasswordChanged;
}
else
{
pb.PasswordChanged -= PasswordChanged;
}
}

private static void PasswordChanged(object sender, RoutedEventArgs e)
{
var pb = sender as PasswordBox;
if (pb == null)
{
return;
}
SetPasswordLength(pb, pb.Password.Length);
}
}
}

+ 129
- 0
GoChat.Controls/PromptAdorner.cs Datei anzeigen

@@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace GoChat.Controls
{
public class PromptAdorner : Adorner
{

public static readonly DependencyProperty PromptCountProperty =
DependencyProperty.RegisterAttached("PromptCount", typeof(int), typeof(PromptAdorner),
new FrameworkPropertyMetadata(0, new PropertyChangedCallback(PromptCountChangedCallBack), new CoerceValueCallback(CoercePromptCountCallback)));

public static int GetPromptCount(DependencyObject obj)
{
return (int)obj.GetValue(PromptCountProperty);
}

public static void SetPromptCount(DependencyObject obj, int value)
{
obj.SetValue(PromptCountProperty, value);
}


public static readonly DependencyProperty IsPromptEnabledProperty =
DependencyProperty.RegisterAttached("IsPromptEnabled", typeof(bool), typeof(PromptAdorner),
new FrameworkPropertyMetadata(false, new PropertyChangedCallback(IsPromptEnabledChangedCallBack), null));

public static bool GetIsPromptEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsPromptEnabledProperty);
}

public static void SetIsPromptEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsPromptEnabledProperty, value);
}


private static object CoercePromptCountCallback(DependencyObject d, object value)
{
int promptCount = (int)value;
promptCount = Math.Max(0, promptCount);

return promptCount;
}

public static void PromptCountChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e) { }

public static void IsPromptEnabledChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var source = d as FrameworkElement;

bool isEnabled = (bool)e.NewValue;
if (isEnabled)
{
//装饰件可用,添加装饰件

AdornerLayer layer = AdornerLayer.GetAdornerLayer(source);
if (layer != null)
{
//能够获取装饰层,说明已经load过了,直接生成装饰件
var adorner = new PromptAdorner(source);
layer.Add(adorner);
}
else
{
//layer为null,说明还未load过(整个可视化树中没有装饰层的情况不考虑)
//在控件的loaded事件内生成装饰件
source.Loaded += (s1, e1) =>
{
var adorner = new PromptAdorner(source);
AdornerLayer.GetAdornerLayer(source).Add(adorner);
};
}
}
else
{
//装饰件不可用,移除装饰件
AdornerLayer layer = AdornerLayer.GetAdornerLayer(source);
if (layer != null)
{
Adorner[] AllAdorners = layer.GetAdorners(source);
if (AllAdorners != null)
{
IEnumerable<Adorner> desAdorners = AllAdorners.Where(p => p is PromptAdorner);
if (desAdorners != null && desAdorners.Count() > 0)
{
desAdorners.ToList().ForEach(p => layer.Remove(p));
}
}
}
}

}


protected override int VisualChildrenCount
{
get { return 1; }
}

public PromptAdorner(UIElement adornedElement)
: base(adornedElement)
{

_chrome = new PromptChrome();
_chrome.DataContext = adornedElement;
this.AddVisualChild(_chrome);
}

protected override Visual GetVisualChild(int index)
{
return _chrome;
}

protected override Size ArrangeOverride(Size arrangeBounds)
{
_chrome.Arrange(new Rect(arrangeBounds));
return arrangeBounds;
}


PromptChrome _chrome;
}
}

+ 31
- 0
GoChat.Controls/PromptChrome.cs Datei anzeigen

@@ -0,0 +1,31 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace GoChat.Controls
{
internal class PromptChrome : Control
{
static PromptChrome()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(PromptChrome), new FrameworkPropertyMetadata(typeof(PromptChrome)));
}

protected override Size ArrangeOverride(Size arrangeBounds)
{

this.Width = 25;
this.Height = 25;

this.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
this.VerticalAlignment = System.Windows.VerticalAlignment.Center;

//TranslateTransform tt = new TranslateTransform();
//tt.X = 5;
//tt.Y = 5;
//this.RenderTransform = tt;

return base.ArrangeOverride(arrangeBounds);
}
}
}

+ 55
- 0
GoChat.Controls/Properties/AssemblyInfo.cs Datei anzeigen

@@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("GoChat.Controls")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GoChat.Controls")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.

//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]


[assembly:ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]


// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

+ 63
- 0
GoChat.Controls/Properties/Resources.Designer.cs Datei anzeigen

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace GoChat.Controls.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GoChat.Controls.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

+ 117
- 0
GoChat.Controls/Properties/Resources.resx Datei anzeigen

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

+ 26
- 0
GoChat.Controls/Properties/Settings.Designer.cs Datei anzeigen

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace GoChat.Controls.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

+ 7
- 0
GoChat.Controls/Properties/Settings.settings Datei anzeigen

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

BIN
GoChat.Controls/Resources/Images/01.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 140 B

BIN
GoChat.Controls/Resources/Images/02.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 140 B

BIN
GoChat.Controls/Resources/Images/03.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 155 B

BIN
GoChat.Controls/Resources/Images/mie.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 97 B

BIN
GoChat.Controls/Resources/Images/mim.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 95 B

BIN
GoChat.Controls/Resources/Images/min.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 94 B

BIN
GoChat.Controls/Resources/Images/mme.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 149 B

BIN
GoChat.Controls/Resources/Images/mmm.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 135 B

BIN
GoChat.Controls/Resources/Images/mmn.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 136 B

BIN
GoChat.Controls/Resources/Images/mxe.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 118 B

BIN
GoChat.Controls/Resources/Images/mxm.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 112 B

BIN
GoChat.Controls/Resources/Images/mxn.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 111 B

BIN
GoChat.Controls/Resources/Images/ske.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 191 B

BIN
GoChat.Controls/Resources/Images/skm.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 168 B

BIN
GoChat.Controls/Resources/Images/skn.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 169 B

BIN
GoChat.Controls/Resources/Images/xe.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 229 B

BIN
GoChat.Controls/Resources/Images/xm.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 229 B

BIN
GoChat.Controls/Resources/Images/xn.png Datei anzeigen

Vorher Nachher
Breite: 27  |  Höhe: 22  |  Größe: 175 B

BIN
GoChat.Controls/Resources/fontawesome/1.png Datei anzeigen

Vorher Nachher
Breite: 1194  |  Höhe: 897  |  Größe: 347 KiB

BIN
GoChat.Controls/Resources/fontawesome/2.png Datei anzeigen

Vorher Nachher
Breite: 1205  |  Höhe: 905  |  Größe: 383 KiB

BIN
GoChat.Controls/Resources/fontawesome/3.png Datei anzeigen

Vorher Nachher
Breite: 1275  |  Höhe: 905  |  Größe: 385 KiB

BIN
GoChat.Controls/Resources/fontawesome/4.png Datei anzeigen

Vorher Nachher
Breite: 1211  |  Höhe: 881  |  Größe: 383 KiB

BIN
GoChat.Controls/Resources/fontawesome/5.png Datei anzeigen

Vorher Nachher
Breite: 1218  |  Höhe: 647  |  Größe: 269 KiB

BIN
GoChat.Controls/Resources/fontawesome/FontAwesome.otf Datei anzeigen


+ 8
- 0
GoChat.Controls/Themes/FontIcon.xaml Datei anzeigen

@@ -0,0 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Style x:Key="FontIconStyle">
<Setter Property="Control.UseLayoutRounding" Value="True"></Setter>
<Setter Property="TextElement.FontFamily" Value="pack://application:,,,/GoChat.Controls;component/Resources/fontawesome/#FontAwesome"></Setter>
</Style>
</ResourceDictionary>

+ 24
- 0
GoChat.Controls/Themes/Generic.xaml Datei anzeigen

@@ -0,0 +1,24 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/FontIcon.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatButton.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatWin.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatScrollViewer.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatTextBox.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatTabControl.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatTabItem.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatTreeView.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatToolTip.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatPasswordBox.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatRichTextBox.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatListBox.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatComboBox.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatMenu.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatBulletCheckBox.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatToggleButton.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/PromptChrome.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type ScrollViewer}" BasedOn="{StaticResource ForScrollviewer}"></Style>
</ResourceDictionary>

+ 72
- 0
GoChat.Controls/Themes/GoChatBulletCheckBox.xaml Datei anzeigen

@@ -0,0 +1,72 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GoChat.Controls.Themes">
<Style TargetType="{x:Type local:BulletCheckBox}">
<Setter Property="Background" Value="#FF4A9E4A"></Setter>
<Setter Property="Foreground" Value="#DDE8E1"></Setter>
<Setter Property="CheckedForeground" Value="White"></Setter>
<Setter Property="CheckedBackground" Value="#FF0CC50C"></Setter>
<Setter Property="FontSize" Value="13"></Setter>
<Setter Property="Cursor" Value="Hand"></Setter>
<Setter Property="Width" Value="75"></Setter>
<Setter Property="Height" Value="28"></Setter>
<Setter Property="Margin" Value="1"></Setter>
<Setter Property="Template">
<Setter.Value>
<!--控件模板-->
<ControlTemplate TargetType="{x:Type local:BulletCheckBox}">
<Viewbox Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Center">
<Border x:Name="border" Width="75" Height="28" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"
Margin="{TemplateBinding Margin}" CornerRadius="14">
<StackPanel Orientation="Horizontal">
<!--状态球-->
<Border x:Name="state" Width="24" Height="24" Margin="3,2,1,2" CornerRadius="12" SnapsToDevicePixels="True"
Background="{TemplateBinding Foreground}">
<Border.RenderTransform>
<TranslateTransform x:Name="transState" X="0"></TranslateTransform>
</Border.RenderTransform>
</Border>
<!--文本框-->
<TextBlock Width="40" Foreground="{TemplateBinding Foreground}" x:Name="txt" Text="{TemplateBinding Text}" VerticalAlignment="Center" TextAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform x:Name="transTxt" X="0"></TranslateTransform>
</TextBlock.RenderTransform>
</TextBlock>
</StackPanel>
</Border>
</Viewbox>

<!--触发器:设置选中状态符号-->
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Text" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedText}" TargetName="txt"/>
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedForeground}" TargetName="state"/>
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedForeground}" TargetName="txt"/>
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedBackground}" TargetName="border"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="transState" Storyboard.TargetProperty="X" To="45" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetName="transTxt" Storyboard.TargetProperty="X" To="-24" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="transState" Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetName="transTxt" Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.5" TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 61
- 0
GoChat.Controls/Themes/GoChatBulletCheckBox.xaml.cs Datei anzeigen

@@ -0,0 +1,61 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace GoChat.Controls.Themes
{
/// <summary>
/// BulletCheckBox.xaml 的交互逻辑
/// </summary>
public class BulletCheckBox : CheckBox
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(BulletCheckBox), new PropertyMetadata("Off"));
/// <summary>
/// 默认文本(未选中)
/// </summary>
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}

public static readonly DependencyProperty CheckedTextProperty = DependencyProperty.Register(
"CheckedText", typeof(string), typeof(BulletCheckBox), new PropertyMetadata("On"));
/// <summary>
/// 选中状态文本
/// </summary>
public string CheckedText
{
get { return (string)GetValue(CheckedTextProperty); }
set { SetValue(CheckedTextProperty, value); }
}

public static readonly DependencyProperty CheckedForegroundProperty =
DependencyProperty.Register("CheckedForeground", typeof(Brush), typeof(BulletCheckBox), new PropertyMetadata(Brushes.WhiteSmoke));
/// <summary>
/// 选中状态前景样式
/// </summary>
public Brush CheckedForeground
{
get { return (Brush)GetValue(CheckedForegroundProperty); }
set { SetValue(CheckedForegroundProperty, value); }
}

public static readonly DependencyProperty CheckedBackgroundProperty =
DependencyProperty.Register("CheckedBackground", typeof(Brush), typeof(BulletCheckBox), new PropertyMetadata(Brushes.LimeGreen));
/// <summary>
/// 选中状态背景色
/// </summary>
public Brush CheckedBackground
{
get { return (Brush)GetValue(CheckedBackgroundProperty); }
set { SetValue(CheckedBackgroundProperty, value); }
}

static BulletCheckBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BulletCheckBox), new FrameworkPropertyMetadata(typeof(BulletCheckBox)));
}
}
}

+ 238
- 0
GoChat.Controls/Themes/GoChatButton.xaml Datei anzeigen

@@ -0,0 +1,238 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GoChat.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/FontIcon.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- bool Visibility转换器 -->
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<!-- 字体图标和文本按钮模板 -->
<ControlTemplate x:Key="FontIconAndTextTemplate" TargetType="{x:Type local:GoChatButton}">
<Border
x:Name="Border"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
UseLayoutRounding="True">
<StackPanel
x:Name="StackPanel"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="Center"
Orientation="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ContentOrientation}">
<TextBlock
x:Name="icon"
Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FontIconMargin}"
VerticalAlignment="Center"
FontSize="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FontIconSize}"
Foreground="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Foreground}"
RenderTransformOrigin="0.5,0.5"
Style="{StaticResource FontIconStyle}"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FontIconValue}"
TextAlignment="Center">
<TextBlock.RenderTransform>
<RotateTransform x:Name="transIcon" Angle="0" />
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock
x:Name="TextBlock"
Padding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TextPadding}"
FontSize="{TemplateBinding FontSize}"
Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Foreground}"
Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Content}"
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsShowText, Converter={StaticResource BooleanToVisibilityConverter}}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MouseOverBackground}" />
<Setter TargetName="icon" Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=MouseOverForeGround}" />
<Setter TargetName="TextBlock" Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=MouseOverForeGround}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="icon" Property="Foreground" Value="LightGray" />
<Setter TargetName="TextBlock" Property="Foreground" Value="LightGray" />
<Setter TargetName="Border" Property="BorderBrush" Value="LightGray" />
</Trigger>
<!-- 动画触发器 -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" />
<Condition Property="IsOpenAnimation" Value="true" />
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="transIcon"
Storyboard.TargetProperty="Angle"
To="180"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="transIcon"
Storyboard.TargetProperty="Angle"
To="0"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</MultiTrigger.ExitActions>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>

<!-- 默认按钮模板 -->
<ControlTemplate x:Key="DefaultTemplate" TargetType="{x:Type local:GoChatButton}">
<Border
x:Name="Border"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
x:Name="TextBlock"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="Center"
FontSize="{TemplateBinding FontSize}"
Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Foreground}"
Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Content}" />
<!-- 附加内容 -->
<ContentControl
x:Name="ContentControl"
Grid.Column="1"
Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FontIconMargin}"
VerticalAlignment="Center"
Template="{TemplateBinding local:ControlAttachProperty.AttachContent}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="ContentControl" Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=MouseOverForeGround}" />
<Setter TargetName="TextBlock" Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=MouseOverForeGround}" />
<Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MouseOverBackground}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="ContentControl" Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=MouseOverForeGround}" />
<Setter TargetName="TextBlock" Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=MouseOverForeGround}" />
<Setter TargetName="Border" Property="Background" Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

<Style x:Key="DefaultStyle" TargetType="{x:Type local:GoChatButton}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Width" Value="150" />
<Setter Property="Height" Value="30" />
<Setter Property="FontSize" Value="13" />
<Setter Property="CornerRadius" Value="0" />
<Setter Property="Foreground" Value="#ffffff" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>

<!-- 默认样式 -->
<Style BasedOn="{StaticResource DefaultStyle}" TargetType="{x:Type local:GoChatButton}">
<Setter Property="Template" Value="{StaticResource DefaultTemplate}" />
<Setter Property="MouseOverForeGround" Value="#ffffff" />
<Setter Property="Content" Value="默认(纯文本)按钮" />
</Style>

<!-- 字体图标和文本按钮样式 -->
<Style x:Key="FontIconAndTextStyle" TargetType="{x:Type local:GoChatButton}">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Width" Value="200" />
<Setter Property="Height" Value="30" />
<Setter Property="FontIconSize" Value="12" />
<Setter Property="CornerRadius" Value="0" />
<Setter Property="Template" Value="{StaticResource FontIconAndTextTemplate}" />
<Setter Property="Foreground" Value="#ffffff" />
<Setter Property="Content" Value="字体图标和文本按钮" />
<Setter Property="FontIconMargin" Value="0,0,5,0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>

<Style x:Key="EllipseStyle" TargetType="{x:Type local:GoChatButton}">
<Setter Property="EllipseStrokeThickness" Value="2" />
<Setter Property="EllipseFillBrush" Value="#FFF4F4F5" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="MouseOverBackground" Value="Transparent" />
<Setter Property="MouseOverForeGround" Value="#d7f0ff" />
<Setter Property="Width" Value="150" />
<Setter Property="Height" Value="150" />
<Setter Property="EllipseHeightAndWidth" Value="100" />
<Setter Property="Margin" Value="0,10,0,0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:GoChatButton}">
<Border
x:Name="border"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Cursor="Hand"
SnapsToDevicePixels="True"
UseLayoutRounding="True">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Ellipse
x:Name="Ellipse"
Width="{TemplateBinding EllipseHeightAndWidth}"
Height="{TemplateBinding EllipseHeightAndWidth}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=EllipseFillBrush}"
Stroke="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=EllipseStroke}" />
<ContentPresenter
x:Name="contentPresenter"
Margin="{TemplateBinding Margin}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Focusable="False"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsShowText, Converter={StaticResource BooleanToVisibilityConverter}}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="border" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MouseOverBackground}" />
<Setter TargetName="Ellipse" Property="Stroke" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MouseOverForeGround}" />
<Setter TargetName="Ellipse" Property="StrokeThickness" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=EllipseStrokeThickness}" />
</Trigger>

</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 395
- 0
GoChat.Controls/Themes/GoChatComboBox.xaml Datei anzeigen

@@ -0,0 +1,395 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:GoChat.Controls"
xmlns:themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/FontIcon.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatScrollViewer.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type ToggleButton}" x:Key="ComboToggleButton">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid x:Name="Grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border Background="{TemplateBinding Background}" x:Name="Bg" Grid.ColumnSpan="2" Margin="0,1,1,1"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Opacity="0.3"/>
<TextBlock Grid.Column="1" x:Name="FIcon" FontSize="{Binding Path=(controls:ControlAttachProperty.FontIconSize),RelativeSource={RelativeSource TemplatedParent}}"
Text="&#xf0d7;"
Foreground="{TemplateBinding Foreground}" Style="{StaticResource FontIconStyle}"
/>
</Grid>
<!--z触发器-->
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#009BDB"/>
<Setter Property="Opacity" TargetName="Bg" Value="0.55" />
</Trigger>
<!--<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
<Setter Property="Opacity" TargetName="Bg" Value="0.6" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
<Setter Property="Opacity" TargetName="Bg" Value="0.6" />
</Trigger>-->
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0" TargetName="Grid"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<!--下拉条目样式-->
<Style TargetType="ComboBoxItem" x:Key="ComboBoxItemStyle">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="RenderOptions.ClearTypeHint" Value="Enabled" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Height" Value="28" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Grid Background="{TemplateBinding Background}" Margin="0,0.5">
<Border x:Name="ItemBackground" IsHitTestVisible="False" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}" />
<ContentPresenter x:Name="contentPresenter" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="ItemBackground" Property="Background" Value="#009BDB" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ItemBackground" Property="Background" Value="#FF77C3FD" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<!--编辑状态文本框样式-->
<Style TargetType="{x:Type TextBox}" x:Key="EditableTextBoxStyle">
<Setter Property="Margin" Value="1"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="MaxLength" Value="2048"/>
<Setter Property="ContextMenu" Value="{DynamicResource TextBoxContextMenu}" />
<Setter Property="Focusable" Value="True"/>
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="SnapsToDevicePixels" Value="True"></Setter>
<Style.Triggers>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="Opacity" Value="0.5"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"></Setter>
</Trigger>
</Style.Triggers>
</Style>


<Style TargetType="{x:Type ComboBox}" x:Key="DefaultComboBox">
<Setter Property="Height" Value="25" />
<Setter Property="Background" Value="#ffffff"/>
<Setter Property="BorderBrush" Value="#009BDB"/>
<Setter Property="controls:ControlAttachProperty.CornerRadius" Value="0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="ItemContainerStyle" Value="{StaticResource ComboBoxItemStyle}" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="MaxDropDownHeight" Value="400" />
<Setter Property="ScrollViewer.CanContentScroll" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid x:Name="PART_Root">
<Border x:Name="Bg" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
CornerRadius="{TemplateBinding controls:ControlAttachProperty.CornerRadius}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--主内容区域-->
<Grid Grid.Column="1" x:Name="ContentSite" Margin="2 0 0 0" >
<ContentPresenter x:Name="PART_SelectedItem" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}"
HorizontalAlignment="Stretch" Margin="2,0,2,0"
IsHitTestVisible="False" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
<!--文本编辑-->
<TextBox x:Name="PART_EditableTextBox" Style="{StaticResource EditableTextBoxStyle}" Visibility="Collapsed"
HorizontalAlignment="Stretch" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" IsHitTestVisible="True"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
IsReadOnly="{TemplateBinding IsReadOnly}" FontFamily="{TemplateBinding FontFamily}" Foreground="{TemplateBinding Foreground}"
Text="{TemplateBinding Text}" FontSize="{TemplateBinding FontSize}" />
</Grid>
<!--下拉按钮-->
<ToggleButton x:Name="PART_DropDownToggle" IsTabStop="False" Style="{StaticResource ComboToggleButton}" VerticalAlignment="Center" Margin="2,0,5,0"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Grid.Column="1" />
</Grid>
<!--弹出下拉控件-->
<Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False"
IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}"
PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Grid Width="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}"
MaxHeight="{Binding MaxDropDownHeight, RelativeSource={RelativeSource TemplatedParent}}">
<Border x:Name="PopupBorder" BorderThickness="1,0,1,1" HorizontalAlignment="Stretch"
Height="Auto" BorderBrush="{TemplateBinding BorderBrush}" Background="#ffffff">
</Border>
<ScrollViewer x:Name="DropDownScrollViewer" BorderThickness="0" Margin="1">
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<!--触发器-->
<ControlTemplate.Triggers>
<!--编辑模式-->
<Trigger Property="IsEditable" Value="True">
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
<Setter TargetName="PART_SelectedItem" Property="Visibility" Value="Collapsed" />
<Setter TargetName="PART_DropDownToggle" Property="Grid.Column" Value="3" />
<Setter TargetName="PART_DropDownToggle" Property="Grid.ColumnSpan" Value="1" />
<Setter TargetName="PART_DropDownToggle" Property="Background" Value="Transparent" />
<Setter Property="IsTabStop" Value="false" />
<Setter TargetName="PART_DropDownToggle" Property="Focusable" Value="False" />
</Trigger>

<!--<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="{Binding Path=(local:ControlAttachProperty.MouseOverBorderBrush),RelativeSource={RelativeSource Self}}"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="{Binding Path=(local:ControlAttachProperty.FocusBorderBrush),RelativeSource={RelativeSource Self}}"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="BorderBrush" Value="{Binding Path=(local:ControlAttachProperty.FocusBorderBrush),RelativeSource={RelativeSource Self}}"/>
</Trigger>-->
<Trigger Property="IsReadOnly" Value="True">
<Setter TargetName="PART_DropDownToggle" Property="Visibility" Value="Collapsed"></Setter>
<Setter Property="BorderThickness" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>



<Geometry x:Key="DownArrowGeometry">M 0 0 L 3.5 4 L 7 0 Z</Geometry>

<Style x:Key="ComboBoxReadonlyToggleButton" TargetType="{x:Type ToggleButton}">
<Setter Property="BorderBrush" Value="{DynamicResource DefaultBorderBrush}"/>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="Chrome" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<Grid HorizontalAlignment="Right" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
<Path x:Name="Arrow" Data="{StaticResource DownArrowGeometry}" Fill="#FF6C7B8B" HorizontalAlignment="Center" Margin="3,1,0,0" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" MappingMode="Absolute" StartPoint="0,0">
<GradientStop Color="#ABADB3" Offset="0.05"/>
<GradientStop Color="#E2E3EA" Offset="0.07"/>
<GradientStop Color="#E3E9EF" Offset="1"/>
</LinearGradientBrush>

<Style x:Key="ComboBoxEditableTextBox" TargetType="{x:Type TextBox}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="MinWidth" Value="0"/>
<Setter Property="MinHeight" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<ScrollViewer x:Name="PART_ContentHost" Background="Transparent" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RoundCorners="false" SnapsToDevicePixels="true" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
<Path x:Name="Arrow" Data="{StaticResource DownArrowGeometry}" Fill="Black" HorizontalAlignment="Center" Margin="0,1,0,0" VerticalAlignment="Center"/>
</themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="Placement" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=Placement}">
<Border x:Name="DropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<ScrollViewer>
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</themes:SystemDropShadowChrome>
</Popup>
<themes:ListBoxChrome x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}"/>
<TextBox x:Name="PART_EditableTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Margin="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ToggleButton Grid.Column="1" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxToggleButton}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsDropDownOpen" Value="true">
<Setter Property="RenderFocused" TargetName="Border" Value="true"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="DropDownBorder" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
<Setter Property="Background" Value="#FFF4F4F4"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
<Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/>
<Setter Property="Color" TargetName="Shdw" Value="#71000000"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

<Style TargetType="ComboBoxItem">
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Padding" Value="5,0,5,0"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}"/>
</Border>

<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#FF77C3FD"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
<!--<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="#FF77C3FD"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>-->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style TargetType="{x:Type ComboBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="{DynamicResource DefaultBorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Padding" Value="4,3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid x:Name="MainGrid" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=MainGrid}">
<Border x:Name="DropDownBorder" BorderBrush="#009BDB" BorderThickness="1,0,1,1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<ScrollViewer CanContentScroll="true" Style="{StaticResource ForScrollviewer}">
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</themes:SystemDropShadowChrome>
</Popup>
<ToggleButton BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxReadonlyToggleButton}"/>
<ContentPresenter Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="false" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="DropDownBorder" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
<Setter Property="Background" Value="#FFF4F4F4"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEditable" Value="true">
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="Template" Value="{StaticResource ComboBoxEditableTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>


</ResourceDictionary>

+ 262
- 0
GoChat.Controls/Themes/GoChatListBox.xaml Datei anzeigen

@@ -0,0 +1,262 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:GoChat.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/FontIcon.xaml" />
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatScrollViewer.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style
x:Key="DisableScrollViewerHorizontalScrollBar"
BasedOn="{StaticResource ForScrollviewer}"
TargetType="{x:Type ScrollViewer}">
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled" />
</Style>
<SolidColorBrush x:Key="Item.MouseOver.Background" Color="#1F26A0DA" />
<SolidColorBrush x:Key="Item.MouseOver.Border" Color="#278CDE" />
<SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#3DDADADA" />
<SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA" />
<SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#3D26A0DA" />
<SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA" />
<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="3" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
x:Name="Bd"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.MouseOver.Background}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.MouseOver.Border}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="False" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedInactive.Background}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedInactive.Border}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedActive.Background}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedActive.Border}" />
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Bd" Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style x:Key="ListBoxItemStyle2" TargetType="{x:Type ListBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0,0,0,1" />
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Height" Value="30" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="controls:ControlAttachProperty.FontIconForeground" Value="#1a90d5" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
x:Name="Bd"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<StackPanel Margin="20,0,0,0" Orientation="Horizontal">
<TextBlock
x:Name="fonticon"
Margin="0,0,5,0"
VerticalAlignment="Center"
FontSize="{TemplateBinding controls:ControlAttachProperty.FontIconSize}"
Style="{StaticResource FontIconStyle}"
Text="{TemplateBinding controls:ControlAttachProperty.FontIconValue}" />
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="#E0E4ED" />
<!--<Setter Property="Foreground" TargetName="fonticon" Value="{Binding Path=(controls:ControlAttachProperty.FontIconForeground),RelativeSource={RelativeSource TemplatedParent}}"/>-->
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="False" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="#2E8AE6" />
<Setter Property="Foreground" Value="White" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="#2E8AE6" />
<Setter Property="Foreground" Value="White" />
<!--<Setter Property="Foreground" Value="{Binding Path=(controls:ControlAttachProperty.FontIconForeground),RelativeSource={RelativeSource TemplatedParent}}"/>-->
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Bd" Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style x:Key="ListBoxItemStyle3" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Margin" Value="3" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
x:Name="Bd"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="BorderBrush" Value="LightSeaGreen" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="False" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedInactive.Background}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedInactive.Border}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedActive.Background}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedActive.Border}" />
<Setter TargetName="Bd" Property="CornerRadius" Value="2" />
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Bd" Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>


<SolidColorBrush x:Key="ListBox.Static.Background" Color="#FFFFFFFF" />
<SolidColorBrush x:Key="ListBox.Static.Border" Color="#FFABADB3" />
<SolidColorBrush x:Key="ListBox.Disabled.Background" Color="#FFFFFFFF" />
<SolidColorBrush x:Key="ListBox.Disabled.Border" Color="#FFD9D9D9" />
<Style TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="{StaticResource ListBox.Static.Background}" />
<Setter Property="BorderBrush" Value="{StaticResource ListBox.Static.Border}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border
x:Name="Bd"
Padding="1"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<ScrollViewer
Padding="{TemplateBinding Padding}"
CanContentScroll="True"
Focusable="false"
Style="{StaticResource DisableScrollViewerHorizontalScrollBar}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Bd" Property="Background" Value="{StaticResource ListBox.Disabled.Background}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource ListBox.Disabled.Border}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true" />
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" />
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 181
- 0
GoChat.Controls/Themes/GoChatMenu.xaml Datei anzeigen

@@ -0,0 +1,181 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:GoChat.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/FontIcon.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<DropShadowEffect x:Key="DefaultDropShadow" Color="Black" BlurRadius="5" ShadowDepth="2" Direction="315" Opacity="0.6" />

<Style x:Key="FIconMenuItem" TargetType="{x:Type MenuItem}">
<Setter Property="Background" Value="#ffffff"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Height" Value="22"/>
<Setter Property="Width" Value="Auto"/>
<Setter Property="Margin" Value="1"/>
<Setter Property="controls:ControlAttachProperty.FontIconSize" Value="14"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<!--Item-->
<Border x:Name="border" Height="{TemplateBinding Height}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<Grid VerticalAlignment="Center" >
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="icon_col" MaxWidth="35" SharedSizeGroup="MenuItemIconColumnGroup"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuTextColumnGroup"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup"/>
<ColumnDefinition Width="10" x:Name="arrow_col" SharedSizeGroup="MenumItemArrow"/>
</Grid.ColumnDefinitions>
<!--icon-->
<TextBlock x:Name="PART_Icon" Text="{TemplateBinding Icon}" Foreground="#009BDB" Margin="3,0,0,0" VerticalAlignment="Center"
FontSize="{TemplateBinding controls:ControlAttachProperty.FontIconSize}" Style="{StaticResource FontIconStyle}"/>
<!--Header-->
<ContentPresenter Grid.Column="1" x:Name="txtHeader" Margin="10,0,0,0" MinWidth="90"
RecognizesAccessKey="True" VerticalAlignment="Center" ContentSource="Header"/>
<!--快捷键 -->
<TextBlock Grid.Column="2" Margin="3,1,3,1" x:Name="IGTHost" Text="{TemplateBinding InputGestureText}"
FontSize="{TemplateBinding FontSize}"
VerticalAlignment="Center" Visibility="Visible" Foreground="{TemplateBinding Foreground}" />
<!--右指针-->
<TextBlock x:Name="PART_Arrow" Grid.Column="3" Text="&#xf0da;" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center"
FontSize="12" Style="{StaticResource FontIconStyle}"/>
<!--淡出子集菜单容器-->
<Popup x:Name="SubMenuPopup" AllowsTransparency="true" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}"
Placement="Bottom" Focusable="false" VerticalOffset="0" HorizontalOffset="5"
PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}">
<Border Background="{TemplateBinding Background}" CornerRadius="0" Margin="5"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True">
<StackPanel Margin="0" IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Grid>
</Border>
</Popup>
</Grid>
</Border>
<!--触发器-->
<ControlTemplate.Triggers>
<!--TopLevelHeader:第一级菜单(有子菜单)-->
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Visibility" Value="Collapsed" TargetName="PART_Arrow"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="IGTHost"/>
<Setter Property="Margin" Value="5,1,1,1" TargetName="PART_Icon"/>
<Setter Property="Margin" Value="1,1,6,1" TargetName="txtHeader"/>
<Setter Property="MinWidth" Value="10" TargetName="txtHeader"/>
<Setter Property="Width" Value="0" TargetName="arrow_col"/>
</Trigger>
<!--TopLevelItem 第一级菜单(无子级)-->
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Visibility" Value="Collapsed" TargetName="PART_Arrow"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="IGTHost"/>
<Setter Property="Margin" Value="5,1,1,1" TargetName="PART_Icon"/>
<Setter Property="Margin" Value="1,1,6,1" TargetName="txtHeader"/>
<Setter Property="MinWidth" Value="10" TargetName="txtHeader"/>
<Setter Property="Width" Value="0" TargetName="arrow_col"/>
</Trigger>
<!--SubmenuHeader:子菜单,有子菜单-->
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Visibility" Value="Visible" TargetName="PART_Arrow"/>
<Setter Property="Placement" Value="Right" TargetName="SubMenuPopup"/>
</Trigger>
<!--SubMenuItem:子菜单,无子级-->
<Trigger Property="Role" Value="SubMenuItem">
<Setter Property="Visibility" Value="Collapsed" TargetName="PART_Arrow"/>
</Trigger>
<!--选中状态,优先级将高于Icon-->
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="PART_Icon" Value="&#xe62a;" Property="Text"></Setter>
<Setter TargetName="PART_Icon" Value="18" Property="FontSize"></Setter>
<Setter TargetName="PART_Icon" Value="#F7B63E" Property="Foreground"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="border" Value="0.5" Property="Opacity"></Setter>
</Trigger>
<!--高亮状态-->
<Trigger Property="IsHighlighted" Value="true">
<Setter Property="Background" TargetName="border" Value="#009BDB"></Setter>
<Setter Property="Foreground" Value="#ffffff"></Setter>
<Setter Property="Foreground" Value="#ffffff" TargetName="PART_Icon"></Setter>
</Trigger>
<!--<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource MenuPressedBackground}"></Setter>
<Setter Property="Foreground" Value="{StaticResource MenuPressedForeground}"></Setter>
</Trigger>-->
<!--子菜单打开状态-->
<!--<Trigger Property="IsSubmenuOpen" Value="true" >
<Setter TargetName="PART_Arrow" Value="{StaticResource CheckedForeground}" Property="Foreground"></Setter>
</Trigger>-->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<!--基于FIconMenuItem的默认样式,提供Header模板-->
<Style x:Key="DefaultMenuItem" TargetType="{x:Type MenuItem}" BasedOn="{StaticResource FIconMenuItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock x:Name="txtHeader" FontSize="{Binding FontSize,RelativeSource={RelativeSource AncestorType={x:Type MenuItem},Mode=FindAncestor}}"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Text="{Binding Header,RelativeSource={RelativeSource AncestorType={x:Type MenuItem},Mode=FindAncestor}}"
Foreground="{Binding Foreground,RelativeSource={RelativeSource AncestorType={x:Type MenuItem},Mode=FindAncestor}}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>

<!--默认右键菜单ContextMenu样式-->
<Style x:Key="DefaultContextMenu" TargetType="{x:Type ContextMenu}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="RenderOptions.ClearTypeHint" Value="Enabled" />
<Setter Property="TextOptions.TextFormattingMode" Value="Ideal" />
<Setter Property="Background" Value="#ffffff"/>
<Setter Property="BorderThickness" Value="1" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Grid.IsSharedSizeScope" Value="True" />
<Setter Property="HasDropShadow" Value="True" />
<Setter Property="ItemContainerStyle" Value="{StaticResource DefaultMenuItem}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Grid>
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3"
BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle"
Grid.IsSharedSizeScope="True" Margin="0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
KeyboardNavigation.TabNavigation="Cycle" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasDropShadow" Value="True">
<Setter TargetName="Border" Property="Effect" Value="{StaticResource DefaultDropShadow}">
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<!--默认Menu样式-->
<Style x:Key="DefaultMenu" TargetType="{x:Type Menu}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="RenderOptions.ClearTypeHint" Value="Enabled" />
<Setter Property="TextOptions.TextFormattingMode" Value="Ideal" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="ItemContainerStyle" Value="{StaticResource DefaultMenuItem}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Menu}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ItemsPresenter Margin="0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 81
- 0
GoChat.Controls/Themes/GoChatPasswordBox.xaml Datei anzeigen

@@ -0,0 +1,81 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:GoChat.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/FontIcon.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatScrollViewer.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<!--bool Visibility转换器-->
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
<Style TargetType="{x:Type PasswordBox}">
<Setter Property="controls:ControlAttachProperty.MouseOverBorderBrush" Value="#1a90d5"/>
<Setter Property="controls:ControlAttachProperty.CornerRadius" Value="2"></Setter>
<Setter Property="controls:ControlAttachProperty.FontIconSize" Value="18"></Setter>
<Setter Property="controls:ControlAttachProperty.WatermarkForeground" Value="#8f908d"></Setter>
<Setter Property="controls:ControlAttachProperty.WatermarkMargin" Value="5,2,5,2"></Setter>
<Setter Property="BorderBrush" Value="#999C9F"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="controls:PasswordBoxWaterMark.IsMonitoring" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border Cursor="IBeam" UseLayoutRounding="True" x:Name="Bd" CornerRadius="{TemplateBinding controls:ControlAttachProperty.CornerRadius}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<Grid Cursor="IBeam" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!--字体图标-->
<TextBlock Grid.Column="0" x:Name="FontIcon" Visibility="{TemplateBinding controls:ControlAttachProperty.IsShowFontIcon,Converter={StaticResource BooleanToVisibilityConverter}}" IsHitTestVisible="False" Style="{StaticResource FontIconStyle}" FontSize="{Binding RelativeSource={RelativeSource TemplatedParent},Path=(controls:ControlAttachProperty.FontIconSize)}" Text="{TemplateBinding controls:ControlAttachProperty.FontIconValue }" Foreground="#8f908d" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="Center" Margin="5,2,5,2"></TextBlock>
<!--水印-->
<TextBlock Grid.Column="1" x:Name="WaterMark" Visibility="Collapsed" Text="{TemplateBinding Tag}" VerticalAlignment="Center" Margin="{TemplateBinding controls:ControlAttachProperty.WatermarkMargin}" Foreground="{TemplateBinding controls:ControlAttachProperty.WatermarkForeground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
<!--文本-->
<ScrollViewer Grid.Column="2" x:Name="PART_ContentHost" VerticalAlignment="Center" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
<!--附加内容-->
<ContentControl Grid.Column="3" Template="{TemplateBinding controls:ControlAttachProperty.AttachContent}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="controls:PasswordBoxWaterMark.PasswordLength" Value="0">
<Setter TargetName="WaterMark" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="WaterMark" Property="Visibility" Value="Collapsed"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"></Condition>
<Condition Property="controls:ControlAttachProperty.IsShowFontIcon" Value="true"></Condition>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="{ Binding RelativeSource={RelativeSource TemplatedParent},Path=(controls:ControlAttachProperty.MouseOverBorderBrush) }" TargetName="FontIcon"/>
</MultiTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="Bd" Value="{Binding Path=(controls:ControlAttachProperty.MouseOverBorderBrush),RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>

+ 89
- 0
GoChat.Controls/Themes/GoChatRichTextBox.xaml Datei anzeigen

@@ -0,0 +1,89 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatScrollViewer.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
<SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>
<Style x:Key="{x:Type TextBoxBase}" TargetType="{x:Type TextBoxBase}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer Style="{StaticResource ForScrollviewer}" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Hidden"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style x:Key="{x:Type Hyperlink}" TargetType="{x:Type Hyperlink}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HotTrackBrushKey}}"/>
<Setter Property="TextDecorations" Value="Underline"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="true">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type RichTextBox}">
<Style.Resources>
<Style TargetType="{x:Type Paragraph}">
<Setter Property="Margin" Value="0"/>
</Style>
<Style x:Key="{x:Type FlowDocument}" TargetType="{x:Type FlowDocument}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
</Style>
<Style x:Key="{x:Type Hyperlink}" BasedOn="{StaticResource {x:Type Hyperlink}}" TargetType="{x:Type Hyperlink}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="Blue"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
</Style.Resources>
<Setter Property="MinWidth" Value="10"/>
<Style.BasedOn>
<StaticResource ResourceKey="{x:Type TextBoxBase}"/>
</Style.BasedOn>
</Style>
</ResourceDictionary>

+ 516
- 0
GoChat.Controls/Themes/GoChatScrollViewer.xaml Datei anzeigen

@@ -0,0 +1,516 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ScrollBarThumb" TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Grid>
<Rectangle
Fill="#90000000"
RadiusX="3"
RadiusY="3" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="HorizontalScrollBarPageButton" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Focusable" Value="false" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Opacity" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Rectangle
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Fill="{TemplateBinding Background}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="VerticalScrollBarPageButton" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Focusable" Value="false" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Opacity" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Rectangle
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Fill="{TemplateBinding Background}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ForScrollbar" TargetType="{x:Type ScrollBar}">
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false" />
<Setter Property="Stylus.IsFlicksEnabled" Value="false" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Margin" Value="0,1,1,6" />
<Setter Property="Width" Value="5" />
<Setter Property="MinWidth" Value="5" />
<Setter Property="Opacity" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="Bg" SnapsToDevicePixels="true">
<Track
x:Name="PART_Track"
IsDirectionReversed="true"
IsEnabled="{TemplateBinding IsMouseOver}">
<Track.DecreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageUpCommand}" Style="{StaticResource VerticalScrollBarPageButton}" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageDownCommand}" Style="{StaticResource VerticalScrollBarPageButton}" />
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumb}" />
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Margin" Value="1,0,6,1" />
<Setter Property="Height" Value="5" />
<Setter Property="MinHeight" Value="5" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Opacity" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="Bg" SnapsToDevicePixels="true">
<Track x:Name="PART_Track" IsEnabled="{TemplateBinding IsMouseOver}">
<Track.DecreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageLeftCommand}" Style="{StaticResource HorizontalScrollBarPageButton}" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageRightCommand}" Style="{StaticResource HorizontalScrollBarPageButton}" />
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumb}" />
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

<!-- ScrollViewer -->
<Style x:Key="ForScrollviewer" TargetType="{x:Type ScrollViewer}">
<Setter Property="BorderBrush" Value="LightGray" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Border
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True">
<Grid Background="{TemplateBinding Background}">
<ScrollContentPresenter
Margin="{TemplateBinding Padding}"
CanContentScroll="{TemplateBinding CanContentScroll}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Cursor="{TemplateBinding Cursor}" />
<ScrollBar
x:Name="PART_VerticalScrollBar"
HorizontalAlignment="Right"
Maximum="{TemplateBinding ScrollableHeight}"
Orientation="Vertical"
Style="{StaticResource ForScrollbar}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{TemplateBinding VerticalOffset}" />
<ScrollBar
x:Name="PART_HorizontalScrollBar"
VerticalAlignment="Bottom"
Maximum="{TemplateBinding ScrollableWidth}"
Orientation="Horizontal"
Style="{StaticResource ForScrollbar}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{TemplateBinding HorizontalOffset}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="ScrollChanged">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="PART_VerticalScrollBar"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:1" />
<DoubleAnimation
BeginTime="0:0:1"
Storyboard.TargetName="PART_VerticalScrollBar"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:1" />
<DoubleAnimation
Storyboard.TargetName="PART_HorizontalScrollBar"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:1" />
<DoubleAnimation
BeginTime="0:0:1"
Storyboard.TargetName="PART_HorizontalScrollBar"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseEnter" SourceName="PART_VerticalScrollBar">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="PART_VerticalScrollBar"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave" SourceName="PART_VerticalScrollBar">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="PART_VerticalScrollBar"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseEnter" SourceName="PART_HorizontalScrollBar">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="PART_HorizontalScrollBar"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave" SourceName="PART_HorizontalScrollBar">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="PART_HorizontalScrollBar"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>



<SolidColorBrush x:Key="ScrollBarDisabledBackground" Color="#F4F4F4"/>
<!--ScrollViewer样式-->
<Style TargetType="ScrollViewer" x:Key="ScrollViewerStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid x:Name="Grid" Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--右下角四方形-->
<Rectangle x:Name="Corner" Grid.Row="1" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<!--内容区域-->
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
<!--竖直滚动条-->
<ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}" Style="{DynamicResource ScrollBarStyle}"/>
<!--水平滚动条-->
<ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{DynamicResource ScrollBarStyle}" ViewportSize="{TemplateBinding ViewportWidth}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>

</Style>

<Style x:Key="VerticalScrollBarPageButton1" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Rectangle Fill="{TemplateBinding Background}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="HorizontalScrollBarPageButton1" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Rectangle Fill="{TemplateBinding Background}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Theum-->
<Style x:Key="ScrollBarThumb1" TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border x:Name="border" CornerRadius="3" Background="#ACACAC" BorderThickness="0" >

</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="border" Value="#888888"/>
</Trigger>
<Trigger Property="IsDragging" Value="True">
<Setter Property="Background" TargetName="border" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--滚动条样式-->
<Style x:Key="ScrollBarStyle" TargetType="{x:Type ScrollBar}">
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Width" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
<Setter Property="MinWidth" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="Bg" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
<RowDefinition Height="0.00001*"/>
<RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
</Grid.RowDefinitions>
<!--上箭头-->

<RepeatButton Style="{DynamicResource ArrowUpPathButton}" Command="{x:Static ScrollBar.LineUpCommand}" IsEnabled="{TemplateBinding IsMouseOver}"/>
<!--滑动条 ? 是不是Slider中的滑动条??? -是 -->
<Track x:Name="PART_Track" IsDirectionReversed="true" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="1">
<!--滑动条上部区域-->
<Track.DecreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageUpCommand}" Style="{StaticResource VerticalScrollBarPageButton1}"/>
</Track.DecreaseRepeatButton>
<!--滑动条部分-->
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageDownCommand}" Style="{StaticResource VerticalScrollBarPageButton1}"/>
</Track.IncreaseRepeatButton>
<!--滑动条下部区域-->
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumb1}" Margin="3,0,3,0"/>
</Track.Thumb>
</Track>
<!--下箭头-->
<RepeatButton Command="{x:Static ScrollBar.LineDownCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="2" Style="{DynamicResource ArrowDownPathButton}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bg" Value="{StaticResource ScrollBarDisabledBackground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<!--水平摆放时-->
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="Width" Value="Auto"/>
<Setter Property="MinWidth" Value="0"/>
<Setter Property="Height" Value="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarHeightKey}}"/>
<Setter Property="MinHeight" Value="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarHeightKey}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="Bg" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/>
<ColumnDefinition Width="0.00001*"/>
<ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/>
</Grid.ColumnDefinitions>
<RepeatButton Command="{x:Static ScrollBar.LineLeftCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{DynamicResource ArrowLeftPathButton}"/>
<Track x:Name="PART_Track" Grid.Column="1" IsEnabled="{TemplateBinding IsMouseOver}">
<Track.DecreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageLeftCommand}" Style="{StaticResource HorizontalScrollBarPageButton1}"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageRightCommand}" Style="{StaticResource HorizontalScrollBarPageButton1}"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumb1}" Margin="0,3,0,3"/>
</Track.Thumb>
</Track>
<RepeatButton Grid.Column="2" Command="{x:Static ScrollBar.LineRightCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{DynamicResource ArrowRightPathButton}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bg" Value="{StaticResource ScrollBarDisabledBackground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

<!--下箭头-->
<Style x:Key="ArrowDownPathButton" TargetType="RepeatButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Grid Background="Transparent">
<Path x:Name="PathFill" Fill="#868999" Width="13" Height="8" StrokeThickness="0" Data="M5.0000001,0 L10,10 L-2.0915641E-08,10 z" RenderTransformOrigin="0.500000001045782,0.5" Stretch="Fill">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="180"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="PathFill" Value="#1C97EA"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Fill" TargetName="PathFill" Value="#FF4D84AE"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--上箭头-->
<Style x:Key="ArrowUpPathButton" TargetType="RepeatButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Grid Background="Transparent">
<Path x:Name="PathFill" Fill="#868999" Width="13" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center" StrokeThickness="0" Data="M5.0000001,0 L10,10 L-2.0915641E-08,10 z" RenderTransformOrigin="0.500000001045782,0.5" Stretch="Fill">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="0"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="PathFill" Value="#1C97EA"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Fill" TargetName="PathFill" Value="#FF4D84AE"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--左箭头-->
<Style x:Key="ArrowLeftPathButton" TargetType="RepeatButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Grid Background="Transparent">
<Path x:Name="PathFill" Fill="#868999" Width="13" Height="8" StrokeThickness="0" Data="M5.0000001,0 L10,10 L-2.0915641E-08,10 z" RenderTransformOrigin="0.500000001045782,0.5" Stretch="Fill">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-90"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="PathFill" Value="#1C97EA"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Fill" TargetName="PathFill" Value="#FF4D84AE"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--右箭头-->
<Style x:Key="ArrowRightPathButton" TargetType="RepeatButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Grid Background="Transparent">
<Path x:Name="PathFill" Fill="#868999" Width="13" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center" StrokeThickness="0" Data="M5.0000001,0 L10,10 L-2.0915641E-08,10 z" RenderTransformOrigin="0.500000001045782,0.5" Stretch="Fill">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="90"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="PathFill" Value="#1C97EA"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Fill" TargetName="PathFill" Value="#FF4D84AE"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 51
- 0
GoChat.Controls/Themes/GoChatTabControl.xaml Datei anzeigen

@@ -0,0 +1,51 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:GoChat.Controls">
<Style TargetType="{x:Type controls:GoChatTabControl}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:GoChatTabControl}">
<Border Name="templateRoot" SnapsToDevicePixels="True" KeyboardNavigation.TabNavigation="Local">
<DockPanel HorizontalAlignment="Stretch" Height="{TemplateBinding Height}" LastChildFill="True" Margin="0"
VerticalAlignment="Stretch" Width="Auto">
<StackPanel Name="HeaderPanel" Background="{TemplateBinding HeaderPanelBackground}" Height="Auto" Width="Auto" DockPanel.Dock="Top" IsItemsHost="True" CanHorizontallyScroll="True" />
<Border Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Width="Auto" DockPanel.Dock="Bottom" Margin="0" Background="{TemplateBinding Background}">
<ContentPresenter Margin="{TemplateBinding Padding}" Name="PART_SelectedContentHost" ContentSource="SelectedContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Height="Auto" />
</Border>
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="TabControl.TabStripPlacement" Value="Top">
<Setter TargetName="HeaderPanel" Property="DockPanel.Dock" Value="Top" />
<Setter TargetName="ContentPanel" Property="DockPanel.Dock" Value="Bottom" />
<Setter TargetName="HeaderPanel" Property="Orientation" Value="Horizontal" />
</Trigger>
<Trigger Property="TabControl.TabStripPlacement" Value="Bottom">
<Setter TargetName="HeaderPanel" Property="DockPanel.Dock" Value="Bottom" />
<Setter TargetName="ContentPanel" Property="DockPanel.Dock" Value="Top" />
</Trigger>
<Trigger Property="TabControl.TabStripPlacement" Value="Left">
<Setter TargetName="HeaderPanel" Property="StackPanel.Orientation" Value="Vertical" />
<Setter TargetName="HeaderPanel" Property="DockPanel.Dock" Value="Left" />
<Setter TargetName="ContentPanel" Property="DockPanel.Dock" Value="Right" />
</Trigger>
<Trigger Property="TabControl.TabStripPlacement" Value="Right">
<Setter TargetName="HeaderPanel" Property="DockPanel.Dock" Value="Right" />
<Setter TargetName="HeaderPanel" Property="StackPanel.Orientation" Value="Vertical" />
<Setter TargetName="ContentPanel" Property="DockPanel.Dock" Value="Left" />
</Trigger>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" Property="Control.Foreground" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 145
- 0
GoChat.Controls/Themes/GoChatTabItem.xaml Datei anzeigen

@@ -0,0 +1,145 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:GoChat.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatButton.xaml" />
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="TabItemSelectedBackground" Color="#F9F9F9" />
<SolidColorBrush x:Key="TabItemHotBorderBrush" Color="#3C7FB1" />
<SolidColorBrush x:Key="TabItemDisabledBackground" Color="#F4F4F4" />
<SolidColorBrush x:Key="TabItemDisabledBorderBrush" Color="#FFC9C7BA" />
<Style TargetType="{x:Type controls:GoChatTabItem}">
<Setter Property="Foreground" Value="White" />
<Setter Property="controls:ControlAttachProperty.MouseOverBackground" Value="#e9f5fc" />
<Setter Property="controls:ControlAttachProperty.TitleBrush" Value="#e9f5fc" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="controls:ControlAttachProperty.FontIconSize" Value="12" />
<Setter Property="controls:ControlAttachProperty.FontIconForeground" Value="White" />
<Setter Property="TabItemHorizontalAlignment" Value="Center" />
<Setter Property="SelectedColorBrush" Value="#3ca0d7" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:GoChatTabItem}">
<Border
x:Name="Bd"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Grid HorizontalAlignment="{TemplateBinding TabItemHorizontalAlignment}" VerticalAlignment="Center">
<TextBlock
x:Name="Tb"
Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:ControlAttachProperty.FontIconMargin)}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
FontSize="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:ControlAttachProperty.FontIconSize)}"
Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:ControlAttachProperty.FontIconForeground)}"
Style="{StaticResource FontIconStyle}"
Text="{TemplateBinding controls:ControlAttachProperty.FontIconValue}" />
<ContentPresenter
x:Name="contentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
ContentSource="Header"
Focusable="False"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Panel.ZIndex" Value="1" />
<Setter TargetName="Bd" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:ControlAttachProperty.TitleBrush)}" />
<Setter TargetName="Tb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedColorBrush}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="false" />
<Condition Property="IsMouseOver" Value="true" />
</MultiTrigger.Conditions>
<Setter TargetName="Tb" Property="Foreground" Value="#1a90d5" />
<Setter TargetName="Bd" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:ControlAttachProperty.MouseOverBackground)}" />
</MultiTrigger>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter TargetName="Bd" Property="BorderThickness" Value="1,0,1,1" />
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter TargetName="Bd" Property="BorderThickness" Value="0,0,0,1" />
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter TargetName="Bd" Property="BorderThickness" Value="0,1,1,1" />
</Trigger>
<Trigger Property="TabStripPlacement" Value="Top">
<Setter TargetName="Bd" Property="BorderThickness" Value="0,1,1,1" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="TabStripPlacement" Value="Left" />
</MultiTrigger.Conditions>
<Setter Property="BorderThickness" Value="0,0,0,1" />
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Bd" Property="Background" Value="{StaticResource TabItemDisabledBackground}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource TabItemDisabledBorderBrush}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>



<Style x:Key="TabItemStyle1" TargetType="{x:Type TabItem}">
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="#E9E9E9" />
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="20,6,20,6" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Border
x:Name="mainBorder"
Margin="0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0" />
<ContentPresenter
x:Name="contentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
ContentSource="Header"
Focusable="False"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Panel.ZIndex" Value="1" />
<Setter TargetName="mainBorder" Property="Background" Value="#ffffff" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="false" />
<Condition Property="IsMouseOver" Value="true" />
</MultiTrigger.Conditions>
<Setter TargetName="mainBorder" Property="Background" Value="#ffffff" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 88
- 0
GoChat.Controls/Themes/GoChatTextBox.xaml Datei anzeigen

@@ -0,0 +1,88 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:GoChat.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/FontIcon.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatScrollViewer.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<!--bool Visibility转换器-->
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
<Style TargetType="{x:Type controls:GoChatTextBox}">
<Setter Property="controls:ControlAttachProperty.MouseOverBorderBrush" Value="#1a90d5"/>
<Setter Property="FontIconMouseOverForeground" Value="#1a90d5"/>
<Setter Property="controls:ControlAttachProperty.CornerRadius" Value="2"></Setter>
<Setter Property="controls:ControlAttachProperty.FontIconSize" Value="18"></Setter>
<Setter Property="controls:ControlAttachProperty.WatermarkForeground" Value="#8f908d"></Setter>
<Setter Property="controls:ControlAttachProperty.WatermarkMargin" Value="5,0,5,0"></Setter>
<Setter Property="controls:ControlAttachProperty.FontIconMargin" Value="5,0,5,0"></Setter>
<Setter Property="BorderBrush" Value="#999C9F"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="controls:ControlAttachProperty.FontIconForeground" Value="#8f908d"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:GoChatTextBox}">
<Border Cursor="IBeam" UseLayoutRounding="True" x:Name="Bd" CornerRadius="{TemplateBinding controls:ControlAttachProperty.CornerRadius}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<Grid Cursor="IBeam" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!--字体图标-->
<TextBlock Grid.Column="0" Foreground="{TemplateBinding controls:ControlAttachProperty.FontIconForeground }" x:Name="FontIcon" Visibility="{TemplateBinding controls:ControlAttachProperty.IsShowFontIcon,Converter={StaticResource BooleanToVisibilityConverter}}" IsHitTestVisible="False" Style="{StaticResource FontIconStyle}" FontSize="{Binding RelativeSource={RelativeSource TemplatedParent},Path=(controls:ControlAttachProperty.FontIconSize)}" Text="{TemplateBinding controls:ControlAttachProperty.FontIconValue }" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="Center" Margin="{TemplateBinding controls:ControlAttachProperty.FontIconMargin}"></TextBlock>
<!--水印-->
<TextBlock Grid.Column="1" x:Name="WatermarkText" IsHitTestVisible="False" Visibility="Collapsed" Text="{TemplateBinding controls:ControlAttachProperty.Watermark}" Foreground="{TemplateBinding controls:ControlAttachProperty.WatermarkForeground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="Center" Margin="{TemplateBinding controls:ControlAttachProperty.WatermarkMargin}"></TextBlock>
<!--文本-->
<ScrollViewer Grid.Column="2" Style="{StaticResource ForScrollviewer}" VerticalAlignment="Center" x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<!--附加内容-->
<ContentControl IsTabStop="False" Grid.Column="3" Template="{TemplateBinding controls:ControlAttachProperty.AttachContent}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
<Setter TargetName="WatermarkText" Property="Visibility" Value="Visible" />
</DataTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="True"></Condition>
<Condition Property="Text" Value=""></Condition>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Collapsed" TargetName="WatermarkText"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"></Condition>
<Condition Property="controls:ControlAttachProperty.IsShowFontIcon" Value="true"></Condition>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="{Binding Path=FontIconMouseOverForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="FontIcon"/>
</MultiTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="Bd" Value="{Binding Path=(controls:ControlAttachProperty.MouseOverBorderBrush),RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>

+ 107
- 0
GoChat.Controls/Themes/GoChatToggleButton.xaml Datei anzeigen

@@ -0,0 +1,107 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:GoChat.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/FontIcon.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle
Margin="2"
SnapsToDevicePixels="true"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
StrokeDashArray="1 2"
StrokeThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD" />
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070" />
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD" />
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1" />
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6" />
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B" />
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4" />
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5" />
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383" />
<Style x:Key="ToggleButtonStyle1" TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Padding" Value="0" />
<Setter Property="Width" Value="25" />
<Setter Property="controls:ControlAttachProperty.FontIconSize" Value="12" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border
x:Name="border"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentPresenter
x:Name="contentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Focusable="False"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<TextBlock
x:Name="TextBlock"
Grid.Column="1"
Margin="{TemplateBinding controls:ControlAttachProperty.FontIconMargin}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="{TemplateBinding controls:ControlAttachProperty.FontIconSize}"
Foreground="{TemplateBinding controls:ControlAttachProperty.FontIconForeground}"
Style="{StaticResource FontIconStyle}"
Text="{TemplateBinding controls:ControlAttachProperty.FontIconValue}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsDefaulted" Value="true">
<Setter TargetName="border" Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="TextBlock" Property="Foreground" Value="#1a90d5" />
<Setter TargetName="border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:ControlAttachProperty.MouseOverBackground)}" />
<!--<Setter Property="BorderThickness" TargetName="border" Value="1"/>-->
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.MouseOver.Border}" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="border" Property="Background" Value="{StaticResource Button.Pressed.Background}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Pressed.Border}" />
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="TextBlock" Property="Foreground" Value="#1a90d5" />
<!--<Setter Property="BorderThickness" TargetName="border" Value="1"/>-->
<Setter TargetName="border" Property="Background" Value="{StaticResource Button.Pressed.Background}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Pressed.Border}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="border" Property="Background" Value="{StaticResource Button.Disabled.Background}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Disabled.Border}" />
<Setter TargetName="contentPresenter" Property="TextElement.Foreground" Value="{StaticResource Button.Disabled.Foreground}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 22
- 0
GoChat.Controls/Themes/GoChatToolTip.xaml Datei anzeigen

@@ -0,0 +1,22 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type ToolTip}">
<Setter Property="Foreground" Value="#ffffff"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Background" Value="#111111"/>
<Setter Property="BorderBrush" Value="#111111"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Grid>
<Border CornerRadius="2" Opacity="0.7" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}">
</Border>
<ContentPresenter Margin="8,5,8,5"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 136
- 0
GoChat.Controls/Themes/GoChatTreeView.xaml Datei anzeigen

@@ -0,0 +1,136 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:GoChat.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/FontIcon.xaml"></ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatScrollViewer.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="ListBorder" Color="#828790"/>
<Style TargetType="{x:Type TreeView}">
<Setter Property="ItemContainerStyle" Value="{DynamicResource DefaultTreeViewItemStyle}"></Setter>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource ListBorder}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeView}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<ScrollViewer Style="{StaticResource ForScrollviewer}" x:Name="_tv_scrollviewer_" Background="{TemplateBinding Background}" CanContentScroll="false" Focusable="false" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
<ItemsPresenter/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
</Trigger>
<Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Setter Property="CanContentScroll" TargetName="_tv_scrollviewer_" Value="true"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>


<Style x:Key="DefaultTreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<StackPanel>
<Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"
MinHeight="{TemplateBinding MinHeight}" UseLayoutRounding="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border>
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</ControlTemplate>
</ToggleButton.Template>
<ToggleButton.Content>
<TextBlock x:Name="ExpanderIcon" Foreground="{TemplateBinding Foreground}" Text="&#xf0da;" Style="{StaticResource FontIconStyle}"
FontSize="{TemplateBinding controls:ControlAttachProperty.FontIconSize}" />
</ToggleButton.Content>
</ToggleButton>
<ContentPresenter Grid.Column="1" x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</Border>
<ItemsPresenter x:Name="ItemsHost" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#F0EBD3"/>
</Trigger>
<Trigger Property="IsExpanded" Value="false">
<Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsExpanded" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter TargetName="ExpanderIcon" Property="Text" Value="&#xf0d7;" />
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="#F0EBD3"/>
<Setter Property="Foreground" Value="#3ca0d7"/>
</Trigger>
<!--<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
</MultiTrigger>-->
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

</ResourceDictionary>

+ 335
- 0
GoChat.Controls/Themes/GoChatWin.xaml Datei anzeigen

@@ -0,0 +1,335 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:gif="https://github.com/XamlAnimatedGif/XamlAnimatedGif"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:GoChat.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/GoChatButton.xaml" />
<ResourceDictionary Source="pack://application:,,,/GoChat.Controls;component/Themes/FontIcon.xaml" />
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="WindowInnerBackground" Color="Transparent" />
<!-- 窗体阴影效果 -->
<DropShadowEffect
x:Key="WindowDropShadow"
BlurRadius="12"
Direction="0"
Opacity="0.7"
ShadowDepth="0" />
<!-- bool Visibility转换器 -->
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<Style x:Key="ResizeGripStyle1" TargetType="{x:Type ResizeGrip}">
<Setter Property="MinWidth" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" />
<Setter Property="MinHeight" Value="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarHeightKey}}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ResizeGrip}">
<Grid Background="{TemplateBinding Background}" SnapsToDevicePixels="true" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:GoChatWin}">
<Setter Property="AllowsTransparency" Value="true" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="ResizeMode" Value="NoResize" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="TitleImageWidth" Value="16" />
<Setter Property="TitleImageHeight" Value="16" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:GoChatWin}">
<Border
x:Name="Bg"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding local:ControlAttachProperty.CornerRadius}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Style="{DynamicResource SkinStyle}"
UseLayoutRounding="True">
<Grid x:Name="Grid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- 标题栏 -->
<Border
x:Name="BgInner"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CaptionHeight}"
VerticalAlignment="Top"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding local:ControlAttachProperty.CaptionCornerRadius}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<Border.Background>
<VisualBrush>
<VisualBrush.Visual>
<Image gif:AnimationBehavior.SourceUri="{TemplateBinding GifSourceUri}" />
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
<i:Interaction.Behaviors>
<local:WinStateBehavior />
</i:Interaction.Behaviors>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- 窗体标题 -->
<StackPanel
Grid.RowSpan="2"
Grid.Column="0"
Orientation="Horizontal">
<Image
Width="{TemplateBinding TitleImageWidth}"
Height="{TemplateBinding TitleImageHeight}"
Margin="5,0,0,0"
Source="{TemplateBinding TitleImageSource}"
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsShowTitleImage, Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBlock
Margin="5,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Foreground="{TemplateBinding local:ControlAttachProperty.TitleBrush}"
Text="{TemplateBinding Title}"
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsShowTitle, Converter={StaticResource BooleanToVisibilityConverter}}" />
</StackPanel>
<!-- 附加内容 -->
<ContentControl
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Grid.ColumnSpan="2"
Template="{TemplateBinding local:ControlAttachProperty.AttachContent}" />
<!-- 窗体按钮:最小化、最大化、关闭 -->
<StackPanel
Grid.Row="0"
Grid.Column="2"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Orientation="Horizontal">
<!-- 最小化 -->
<local:GoChatButton
Width="27"
Height="22"
Content="{x:Null}"
CornerRadius="0"
ToolTip="最小化"
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MinIsEnable, Converter={StaticResource BooleanToVisibilityConverter}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:ChangePropertyAction
PropertyName="WindowState"
TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
Value="Minimized" />
</i:EventTrigger>
</i:Interaction.Triggers>
<local:GoChatButton.Background>
<ImageBrush ImageSource="../Resources/Images/min.png" />
</local:GoChatButton.Background>
<local:GoChatButton.MouseOverBackground>
<ImageBrush ImageSource="../Resources/Images/mim.png" />
</local:GoChatButton.MouseOverBackground>
<local:GoChatButton.PressBackGround>
<ImageBrush ImageSource="../Resources/Images/mie.png" />
</local:GoChatButton.PressBackGround>
</local:GoChatButton>
<!-- 最大化 -->
<local:GoChatButton
x:Name="btnMax"
Width="27"
Height="22"
Content="{x:Null}"
CornerRadius="0"
ToolTip="最大化"
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MaxIsEnable, Converter={StaticResource BooleanToVisibilityConverter}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:ChangePropertyAction
PropertyName="WindowState"
TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
Value="Maximized" />
</i:EventTrigger>
</i:Interaction.Triggers>
<local:GoChatButton.Background>
<ImageBrush ImageSource="../Resources/Images/mxn.png" />
</local:GoChatButton.Background>
<local:GoChatButton.MouseOverBackground>
<ImageBrush ImageSource="../Resources/Images/mxm.png" />
</local:GoChatButton.MouseOverBackground>
<local:GoChatButton.PressBackGround>
<ImageBrush ImageSource="../Resources/Images/mxe.png" />
</local:GoChatButton.PressBackGround>
</local:GoChatButton>
<!-- 还原 -->
<local:GoChatButton
x:Name="btnRestore"
Width="27"
Height="22"
Content="{x:Null}"
CornerRadius="0"
ToolTip="还原"
Visibility="Collapsed">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:ChangePropertyAction
PropertyName="WindowState"
TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
Value="Normal" />
</i:EventTrigger>
</i:Interaction.Triggers>
<local:GoChatButton.Background>
<ImageBrush ImageSource="../Resources/Images/01.png" />
</local:GoChatButton.Background>
<local:GoChatButton.MouseOverBackground>
<ImageBrush ImageSource="../Resources/Images/02.png" />
</local:GoChatButton.MouseOverBackground>
<local:GoChatButton.PressBackGround>
<ImageBrush ImageSource="../Resources/Images/03.png" />
</local:GoChatButton.PressBackGround>
</local:GoChatButton>
<!-- 关闭 -->
<local:GoChatButton
Width="27"
Height="22"
Content="{x:Null}"
CornerRadius="0,4,0,0"
ToolTip="关闭"
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CloseIsEnable, Converter={StaticResource BooleanToVisibilityConverter}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<local:GoChatButton.Background>
<ImageBrush ImageSource="../Resources/Images/xn.png" />
</local:GoChatButton.Background>
<local:GoChatButton.MouseOverBackground>
<ImageBrush ImageSource="../Resources/Images/xm.png" />
</local:GoChatButton.MouseOverBackground>
<local:GoChatButton.PressBackGround>
<ImageBrush ImageSource="../Resources/Images/xe.png" />
</local:GoChatButton.PressBackGround>
</local:GoChatButton>
</StackPanel>
</Grid>
</Border>
<!-- 内容区域 -->
<AdornerDecorator Grid.Row="1">
<ContentPresenter />
</AdornerDecorator>
<ContentControl Grid.Row="2" />
<Rectangle
x:Name="RectangleZy"
Grid.Row="0"
Grid.RowSpan="3"
Width="5"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Cursor="SizeWE"
Fill="Transparent"
Visibility="Collapsed">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<local:ExInvokeCommandAction Command="{Binding MouseLeftButtonDownCommand, RelativeSource={RelativeSource TemplatedParent}}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonUp">
<local:ExInvokeCommandAction Command="{Binding MouseLeftButtonUpCommand, RelativeSource={RelativeSource TemplatedParent}}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<local:ExInvokeCommandAction Command="{Binding MouseMoveCommand, RelativeSource={RelativeSource TemplatedParent}}" CommandParameter="zy" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
<Rectangle
x:Name="RectangleSx"
Grid.Row="0"
Grid.RowSpan="3"
Height="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Cursor="SizeNS"
Fill="Transparent"
Visibility="Collapsed">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<local:ExInvokeCommandAction Command="{Binding MouseLeftButtonDownCommand, RelativeSource={RelativeSource TemplatedParent}}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonUp">
<local:ExInvokeCommandAction Command="{Binding MouseLeftButtonUpCommand, RelativeSource={RelativeSource TemplatedParent}}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<local:ExInvokeCommandAction Command="{Binding MouseMoveCommand, RelativeSource={RelativeSource TemplatedParent}}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
<ResizeGrip
x:Name="ResizeGrip"
Grid.Row="0"
Grid.RowSpan="3"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
IsTabStop="False"
Style="{StaticResource ResizeGripStyle1}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsShowOpenLinearGradient" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Bg" Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[2].(GradientStop.Offset)">
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0.513" />
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Bg" Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[0].(GradientStop.Offset)">
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0.513" />
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Setter TargetName="Bg" Property="OpacityMask">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#FF08080F" />
<GradientStop Offset="1" Color="#00000000" />
<GradientStop Color="#00000000" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="ResizeMode" Value="CanResizeWithGrip">
<Setter TargetName="RectangleZy" Property="Visibility" Value="Visible" />
<Setter TargetName="RectangleSx" Property="Visibility" Value="Visible" />
<Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" />
</Trigger>
<Trigger Property="WindowState" Value="Maximized">
<Setter TargetName="btnMax" Property="Visibility" Value="Collapsed" />
<Setter TargetName="btnRestore" Property="Visibility" Value="Visible" />
</Trigger>
<!-- 是否显示背景遮罩效果 -->
<Trigger Property="IsShowBackGroundEffet" Value="true">
<Setter TargetName="Bg" Property="Margin" Value="6" />
<Setter TargetName="Bg" Property="Effect" Value="{StaticResource WindowDropShadow}" />
</Trigger>
<Trigger Property="IsGifBackground" Value="False">
<Setter TargetName="BgInner" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CaptionBackGround}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 76
- 0
GoChat.Controls/Themes/PromptChrome.xaml Datei anzeigen

@@ -0,0 +1,76 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GoChat.Controls.Themes"
xmlns:controls="clr-namespace:GoChat.Controls">
<Style TargetType="{x:Type controls:PromptChrome}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:PromptChrome}">
<Grid x:Name="container">
<!--最外圈的白色圆框,并对其作阴影效果-->
<!--<Ellipse Fill="White">
<Ellipse.Effect>
<DropShadowEffect BlurRadius="6"
ShadowDepth="6"
Opacity="0.8"
Direction="270"
RenderingBias="Performance"/>
</Ellipse.Effect>
</Ellipse>-->

<!--内部的上半圆-->
<Ellipse Margin="3">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#FFF4AEB1"/>
<GradientStop Offset="0.5" Color="#FFE3313A"/>
<GradientStop Offset="1" Color="#FFE3313A"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>

<!--内部的下半圆,通过采用Exclude模式合并上下两个圆来完成-->
<Path HorizontalAlignment="Center" VerticalAlignment="Center">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Exclude" >
<CombinedGeometry.Geometry1>
<EllipseGeometry Center="7 7" RadiusX="7" RadiusY="7" />
</CombinedGeometry.Geometry1>

<CombinedGeometry.Geometry2>
<EllipseGeometry Center="7 0" RadiusX="9" RadiusY="7"/>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>

<Path.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#FFDF151F"/>
<GradientStop Offset="1" Color="#FFBA0004"/>
</LinearGradientBrush>
</Path.Fill>
</Path>

<Viewbox Stretch="Uniform" >
<!--绑定上文中的PromptCount属性-->
<Label Content="{Binding Path=(controls:PromptAdorner.PromptCount)}"
x:Name="label"
Foreground="White"
FontWeight="Bold"
FontSize="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Viewbox>
</Grid>

<ControlTemplate.Triggers>
<!--使用数据触发器,当PromptCount为0时,隐藏提示-->
<DataTrigger Binding="{Binding Path=(controls:PromptAdorner.PromptCount)}" Value="0">
<Setter TargetName="container" Property="Visibility" Value="Hidden"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

+ 69
- 0
GoChat.Controls/WinStateBehavior.cs Datei anzeigen

@@ -0,0 +1,69 @@
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Media;

namespace GoChat.Controls
{
/// <summary>
/// 全局窗体行为
/// </summary>
public class WinStateBehavior : Behavior<UIElement>
{
private GoChatWin _win;
protected override void OnAttached()
{
base.OnAttached();
var parent = VisualTreeHelper.GetParent(AssociatedObject);
while (parent != null)
{
var window = parent as GoChatWin;
if (window != null)
{
_win= window;
}
parent = VisualTreeHelper.GetParent(parent);
}
AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
_win.StateChanged += _win_StateChanged;
}

/// <summary>
/// 解决ShowInTaskbar == false时最小化窗体的时候在桌面左下角显示的问题
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _win_StateChanged(object sender, System.EventArgs e)
{
var state = _win.WindowState;
if (state == WindowState.Minimized && _win.ShowInTaskbar == false)
{
_win.Hide();
}
if (_win.ResizeMode == ResizeMode.CanResizeWithGrip && state == WindowState.Maximized && _win.Name == "MainWin")
{
_win.WindowState = WindowState.Normal;
_win.Height = SystemParameters.PrimaryScreenHeight - 50;
}
}

protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.MouseLeftButtonDown -= AssociatedObject_MouseLeftButtonDown;
_win.StateChanged -= _win_StateChanged;
}

/// <summary>
/// 双击窗体标题栏改变窗体最大化最小化状态
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void AssociatedObject_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (e.ClickCount == 2 && _win.TitleIsSupportChangeWindowState)
{
_win.WindowState = _win.WindowState == WindowState.Normal ? WindowState.Maximized : WindowState.Normal;
}
}
}
}

+ 4
- 0
GoChat.Controls/packages.config Datei anzeigen

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="XamlAnimatedGif" version="1.1.10" targetFramework="net451" />
</packages>

+ 17
- 0
GoChat.Infrastructure/CommonException.cs Datei anzeigen

@@ -0,0 +1,17 @@
using System;

namespace GoChat.Infrastructure
{
public class CommonException : Exception
{

public CommonException(string message):base(message)
{
}
public CommonException(string message, Exception innerException) : base(message, innerException)
{

}
}
}

+ 106
- 0
GoChat.Infrastructure/DESEncrypt.cs Datei anzeigen

@@ -0,0 +1,106 @@
using System;
using System.Security.Cryptography;
using System.Text;

namespace Learun.Util
{
/// <summary>
/// 版 本 Learun-ADMS-Ultimate V7.0.0 力软敏捷开发框架
/// Copyright (c) 2013-2018 上海力软信息技术有限公司
/// 创建人:陈彬彬
/// 日 期:2017.03.04
/// 描 述:加密、解密帮助类
/// </summary>
public class DESEncrypt
{
private static string key = "Learun###***";

#region ========加密========
/// <summary>
/// 加密
/// </summary>
/// <param name="Text">需要加密的内容</param>
/// <returns></returns>
public static string Encrypt(string Text)
{
return Encrypt(Text, key);
}
/// <summary>
/// 加密数据
/// </summary>
/// <param name="Text">需要加密的内容</param>
/// <param name="sKey">秘钥</param>
/// <returns></returns>
public static string Encrypt(string Text, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray;
inputByteArray = Encoding.Default.GetBytes(Text);
des.Key = ASCIIEncoding.ASCII.GetBytes(Md5Helper.Hash(sKey).ToUpper().Substring(0, 8));
des.IV = ASCIIEncoding.ASCII.GetBytes(Md5Helper.Hash(sKey).ToUpper().Substring(0, 8));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
return ret.ToString();
}

#endregion

#region ========解密========
/// <summary>
/// 解密
/// </summary>
/// <param name="Text">需要解密的内容</param>
/// <returns></returns>
public static string Decrypt(string Text)
{
if (!string.IsNullOrEmpty(Text))
{
return Decrypt(Text, key);
}
else
{
return "";
}
}
/// <summary>
/// 解密数据
/// </summary>
/// <param name="Text">需要解密的内容</param>
/// <param name="sKey">秘钥</param>
/// <returns></returns>
public static string Decrypt(string Text, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
int len;
len = Text.Length / 2;
byte[] inputByteArray = new byte[len];
int x, i;
for (x = 0; x < len; x++)
{
i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
inputByteArray[x] = (byte)i;
}
des.Key = ASCIIEncoding.ASCII.GetBytes(Md5Helper.Hash(sKey).ToUpper().Substring(0, 8));
des.IV = ASCIIEncoding.ASCII.GetBytes(Md5Helper.Hash(sKey).ToUpper().Substring(0, 8));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}

public static string Decrypt(string uPPass, object p, object sSOPublicSecret)
{
throw new NotImplementedException();
}

#endregion
}
}

+ 67
- 0
GoChat.Infrastructure/EnumExtensions.cs Datei anzeigen

@@ -0,0 +1,67 @@
using System;
using System.Collections;
using System.Reflection;
using System.Windows.Markup;

namespace GoChat.Infrastructure
{
/// <summary>
/// 枚举扩展方法类
/// </summary>
public static class EnumExtensions
{
/// <summary>
/// 获取枚举项的Description特性的描述文字
/// </summary>
/// <param name="enumeration"> </param>
/// <returns> </returns>
public static string ToDescription(this Enum enumeration)
{
Type type = enumeration.GetType();
MemberInfo[] members = type.GetMember(enumeration.CastTo<string>());
if (members.Length > 0)
{
return members[0].ToDescription();
}
return enumeration.CastTo<string>();
}
}

[MarkupExtensionReturnType(typeof(IEnumerable))]

public class EnumValuesExtension : MarkupExtension

{

public EnumValuesExtension()

{

}

public EnumValuesExtension(Type enumType)

{

this.EnumType = enumType;

}

[ConstructorArgument("enumType")]

public Type EnumType { get; set; }

public override object ProvideValue(IServiceProvider serviceProvider)

{

if (this.EnumType == null)

throw new ArgumentException("The enum type is not set");

return Enum.GetValues(this.EnumType);

}

}
}

+ 74
- 0
GoChat.Infrastructure/GoChat.Infrastructure.csproj Datei anzeigen

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{71BEFA2E-3359-4C93-A1BF-4C0E3FC1E905}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GoChat.Infrastructure</RootNamespace>
<AssemblyName>GoChat.Infrastructure</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>GoChat.Infrastructure</SccProjectName>
<SccLocalPath>1~a7250b02-76e9-4d74-aa27-f5cdf7719296</SccLocalPath>
<SccAuxPath>http://123.57.209.16:8090/VaultService</SccAuxPath>
<SccProvider>SourceGear Vault Visual Studio 2005 Client:{1EA47954-8515-402d-82D9-B5C332120A8D}</SccProvider>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite, Version=1.0.105.2, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\packages\System.Data.SQLite.Core.1.0.105.2\lib\net451\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CommonException.cs" />
<Compile Include="DESEncrypt.cs" />
<Compile Include="EnumExtensions.cs" />
<Compile Include="Md5Helper.cs" />
<Compile Include="MemoryOptimization.cs" />
<Compile Include="ObjectExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SqLiteHelper.cs" />
<Compile Include="TypeExtensions.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\System.Data.SQLite.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\System.Data.SQLite.Core.targets'))" />
</Target>
</Project>

+ 54
- 0
GoChat.Infrastructure/Md5Helper.cs Datei anzeigen

@@ -0,0 +1,54 @@
using System.Security.Cryptography;
using System.Text;

namespace Learun.Util
{
/// <summary>
/// 版 本 Learun-ADMS-Ultimate V7.0.0 力软敏捷开发框架
/// Copyright (c) 2013-2018 上海力软信息技术有限公司
/// 创建人:陈彬彬
/// 日 期:2017.03.04
/// 描 述:数据访问(SqlServer) 上下文
/// </summary>
public class Md5Helper
{
#region "MD5加密"
/// <summary>
/// MD5加密
/// </summary>
/// <param name="str">加密字符</param>
/// <param name="code">加密位数16/32</param>
/// <returns></returns>
public static string Encrypt(string str, int code)
{
string strEncrypt = string.Empty;
if (code == 16)
{
strEncrypt = Hash(str).Substring(8, 16);
}

if (code == 32)
{
strEncrypt = Hash(str);
}
return strEncrypt;
}
/// <summary>
/// 32位MD5加密(小写)
/// </summary>
/// <param name="input">输入字段</param>
/// <returns></returns>
public static string Hash(string input)
{
MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
#endregion
}
}

+ 97
- 0
GoChat.Infrastructure/MemoryOptimization.cs Datei anzeigen

@@ -0,0 +1,97 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32;

namespace GoChat.Infrastructure
{
/// <summary>
/// 内存优化
/// </summary>
public class MemoryOptimization
{
private const string Data = "SOFTWARE\\FeiXing\\Components";

private const string Keys = "LastAboutShowedTime";

private const string Formate = "MM/dd/yyyy HH:mm:ss";

private const string Disable = "DisableSmartTag";

private const string SmartTagWidth = "SmartTagWidth";

private void SetDate()
{
CreateKey();
var expr_0B = Registry.CurrentUser;
var expr17 = expr_0B.OpenSubKey(Data, true);
if (expr17 != null)
{
expr17.GetValue(Keys);
var value = DateTime.Now.ToString(Formate);
expr17.SetValue(Keys, value);
}
expr_0B.Dispose();
}

[DllImport("kernel32.dll")]
private static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);

private void FlushMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
}
}

private void CreateKey()
{
var currentUser = Registry.CurrentUser;
if (currentUser.OpenSubKey(Data, true) == null)
{
var expr_1F = currentUser.CreateSubKey(Data);
if (expr_1F != null)
{
var registryKey = expr_1F.CreateSubKey(Keys);
if (registryKey != null)
registryKey.SetValue(Keys, DateTime.Now.ToString(Formate));
var subKey = expr_1F.CreateSubKey(Disable);
if (subKey != null)
subKey.SetValue(Keys, false);
var key = expr_1F.CreateSubKey(SmartTagWidth);
if (key != null)
key.SetValue(Keys, 350);
}
}
currentUser.Dispose();
}

/// <summary>
/// 指定时间进行内存优化,默认30秒
/// </summary>
/// <param name="sleepSpan"></param>
public void Cracker(int sleepSpan = 30)
{
Task.Factory.StartNew(delegate
{
while (true)
{
try
{
SetDate();
FlushMemory();
Thread.Sleep(TimeSpan.FromSeconds((double)sleepSpan));
}
catch (Exception)
{
}
}
});
}
}
}

+ 65
- 0
GoChat.Infrastructure/ObjectExtensions.cs Datei anzeigen

@@ -0,0 +1,65 @@
using System;

namespace GoChat.Infrastructure
{
/// <summary>
/// 通用类型扩展方法类
/// </summary>
public static class ObjectExtensions
{
/// <summary>
/// 把对象类型转化为指定类型,转化失败时返回该类型默认值
/// </summary>
/// <typeparam name="T"> 动态类型 </typeparam>
/// <param name="value"> 要转化的源对象 </param>
/// <returns> 转化后的指定类型的对象,转化失败返回类型的默认值 </returns>
public static T CastTo<T>(this object value)
{
object result;
Type type = typeof (T);
try
{
if (type.IsEnum)
{
result = Enum.Parse(type, value.ToString());
}
else if (type == typeof (Guid))
{
result = Guid.Parse(value.ToString());
}
else
{
result = Convert.ChangeType(value, type);
}
}
catch
{
result = default(T);
}

return (T)result;
}

/// <summary>
/// 把对象类型转化为指定类型,转化失败时返回指定的默认值
/// </summary>
/// <typeparam name="T"> 动态类型 </typeparam>
/// <param name="value"> 要转化的源对象 </param>
/// <param name="defaultValue"> 转化失败返回的指定默认值 </param>
/// <returns> 转化后的指定类型对象,转化失败时返回指定的默认值 </returns>
public static T CastTo<T>(this object value, T defaultValue)
{
object result;
Type type = typeof (T);
try
{
result = type.IsEnum ? Enum.Parse(type, value.ToString()) : Convert.ChangeType(value, type);
}
catch
{
result = defaultValue;
}
return (T)result;
}
}
}

+ 36
- 0
GoChat.Infrastructure/Properties/AssemblyInfo.cs Datei anzeigen

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("GoChat.Infrastructure")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GoChat.Infrastructure")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("71befa2e-3359-4c93-a1bf-4c0e3fc1e905")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

+ 519
- 0
GoChat.Infrastructure/SqLiteHelper.cs Datei anzeigen

@@ -0,0 +1,519 @@
using System;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;

namespace GoChat.Sqlite
{

/// <summary>
/// SQLite数据库帮助静态类
/// </summary>
public class SqLiteHelper
{

/// <summary>
/// 数据库连接字符串
/// </summary>
static readonly string ConnectionString = "Data Source=" + AppDomain.CurrentDomain.BaseDirectory + @"profiles\fx;Pooling=true;FailIfMissing=false;Password=fx123";

#region 执行数据库操作(新增、更新或删除),返回影响行数
/// <summary>
/// 执行数据库操作(新增、更新或删除)
/// </summary>
/// <param name="cmd">SqlCommand对象</param>
/// <returns>所受影响的行数</returns>
public static int ExecuteNonQuery(SQLiteCommand cmd)
{
int result;
using (var con = new SQLiteConnection(ConnectionString))
{
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, true, cmd.CommandType, cmd.CommandText);
try
{
result = cmd.ExecuteNonQuery();
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
}
return result;
}

/// <summary>
/// 执行数据库操作(新增、更新或删除)
/// </summary>
/// <param name="commandText">执行语句或存储过程名</param>
/// <param name="commandType">执行类型(默认语句)</param>
/// <returns>所受影响的行数</returns>
public static int ExecuteNonQuery(string commandText, CommandType commandType = CommandType.Text)
{
int result;
var cmd = new SQLiteCommand();
using (var con = new SQLiteConnection(ConnectionString))
{
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, true, commandType, commandText);
try
{
result = cmd.ExecuteNonQuery();
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
}
return result;
}

/// <summary>
/// 执行数据库操作(新增、更新或删除)
/// </summary>
/// <param name="commandText">执行语句或存储过程名</param>
/// <param name="commandType">执行类型(默认语句)</param>
/// <param name="cmdParms">SQL参数对象</param>
/// <returns>所受影响的行数</returns>
public static int ExecuteNonQuery(string commandText, CommandType commandType = CommandType.Text, params SQLiteParameter[] cmdParms)
{
int result;
var cmd = new SQLiteCommand();
using (var con = new SQLiteConnection(ConnectionString))
{
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, true, commandType, commandText, cmdParms);
try
{
result = cmd.ExecuteNonQuery();
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
}
return result;
}
#endregion


#region 构建一个SQLiteParameter
/// <summary>
/// 构建一个SQLiteParameter
/// </summary>
/// <param name="name">参数名字</param>
/// <param name="type">参数类型</param>
/// <param name="value">参数值</param>
/// <returns>SQLiteParameter的值</returns>
public static SQLiteParameter MakeSqLiteParameter(string name, DbType type, object value)
{
var parm = new SQLiteParameter(name, type) {Value = value};
return parm;
}

#endregion

#region 执行数据库操作(新增、更新或删除)同时返回执行后查询所得的第1行第1列数据
/// <summary>
/// 执行数据库操作(新增、更新或删除)同时返回执行后查询所得的第1行第1列数据
/// </summary>
/// <param name="cmd">SqlCommand对象</param>
/// <returns>查询所得的第1行第1列数据</returns>
public static object ExecuteScalar(SQLiteCommand cmd)
{
object result;
using (var con = new SQLiteConnection(ConnectionString))
{
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, true, cmd.CommandType, cmd.CommandText);
try
{
result = cmd.ExecuteScalar();
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
}
return result;
}


public static bool Exists(string strSql)
{
var obj = ExecuteScalar(strSql);
bool cmdresult;
if ((Equals(obj, null)) || (Equals(obj, DBNull.Value)))
{
cmdresult =false;
}
else
{
cmdresult = true;
}
return cmdresult;
}

/// <summary>
/// 执行数据库操作(新增、更新或删除)同时返回执行后查询所得的第1行第1列数据
/// </summary>
/// <param name="commandText">执行语句或存储过程名</param>
/// <param name="commandType">执行类型(默认语句)</param>
/// <returns>查询所得的第1行第1列数据</returns>
public static object ExecuteScalar(string commandText, CommandType commandType = CommandType.Text)
{
object result;
var cmd = new SQLiteCommand();
using (var con = new SQLiteConnection(ConnectionString))
{
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, true, commandType, commandText);
try
{
result = cmd.ExecuteScalar();
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
}
return result;
}

/// <summary>
/// 执行数据库操作(新增、更新或删除)同时返回执行后查询所得的第1行第1列数据
/// </summary>
/// <param name="commandText">执行语句或存储过程名</param>
/// <param name="commandType">执行类型(默认语句)</param>
/// <param name="cmdParms">SQL参数对象</param>
/// <returns>查询所得的第1行第1列数据</returns>
public static object ExecuteScalar(string commandText, CommandType commandType = CommandType.Text, params SQLiteParameter[] cmdParms)
{
object result;
var cmd = new SQLiteCommand();
using (var con = new SQLiteConnection(ConnectionString))
{
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, true, commandType, commandText, cmdParms);
try
{
result = cmd.ExecuteScalar();
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
}
return result;
}
#endregion

#region 执行数据库查询,返回SqlDataReader对象
/// <summary>
/// 执行数据库查询,返回SqlDataReader对象
/// </summary>
/// <param name="cmd">SqlCommand对象</param>
/// <returns>SqlDataReader对象</returns>
public static DbDataReader ExecuteReader(SQLiteCommand cmd)
{
DbDataReader reader;
var con = new SQLiteConnection(ConnectionString);
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, false, cmd.CommandType, cmd.CommandText);
try
{
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception ex)
{
throw ex;
}
return reader;
}

/// <summary>
/// 执行数据库查询,返回SqlDataReader对象
/// </summary>
/// <param name="commandText">执行语句或存储过程名</param>
/// <param name="commandType">执行类型(默认语句)</param>
/// <returns>SqlDataReader对象</returns>
public static DbDataReader ExecuteReader(string commandText, CommandType commandType = CommandType.Text)
{
DbDataReader reader = null;
if (string.IsNullOrEmpty(ConnectionString))
throw new Exception("connectionString");
if (string.IsNullOrEmpty(commandText))
throw new ArgumentNullException("commandText");

var con = new SQLiteConnection(ConnectionString);
var cmd = new SQLiteCommand();
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, false, commandType, commandText);
try
{
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception ex)
{
throw ex;
}
return reader;
}

/// <summary>
/// 执行数据库查询,返回SqlDataReader对象
/// </summary>
/// <param name="commandText">执行语句或存储过程名</param>
/// <param name="commandType">执行类型(默认语句)</param>
/// <param name="cmdParms">SQL参数对象</param>
/// <returns>SqlDataReader对象</returns>
public static DbDataReader ExecuteReader(string commandText, CommandType commandType = CommandType.Text, params SQLiteParameter[] cmdParms)
{
DbDataReader reader;
if (string.IsNullOrEmpty(ConnectionString))
throw new Exception("connectionString");
if (string.IsNullOrEmpty(commandText))
throw new ArgumentNullException("commandText");

var con = new SQLiteConnection(ConnectionString);
var cmd = new SQLiteCommand();
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, false, commandType, commandText, cmdParms);
try
{
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception ex)
{
throw ex;
}
return reader;
}
#endregion

#region 执行数据库查询,返回DataSet对象
/// <summary>
/// 执行数据库查询,返回DataSet对象
/// </summary>
/// <param name="cmd">SqlCommand对象</param>
/// <returns>DataSet对象</returns>
public static DataSet ExecuteDataSet(SQLiteCommand cmd)
{
var ds = new DataSet();
var con = new SQLiteConnection(ConnectionString);
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, false, cmd.CommandType, cmd.CommandText);
try
{
var sda = new SQLiteDataAdapter(cmd);
sda.Fill(ds);
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (cmd.Connection != null)
{
if (cmd.Connection.State == ConnectionState.Open)
{
cmd.Connection.Close();
}
}
}
return ds;
}

/// <summary>
/// 执行数据库查询,返回DataSet对象
/// </summary>
/// <param name="commandText">执行语句或存储过程名</param>
/// <param name="commandType">执行类型(默认语句)</param>
/// <returns>DataSet对象</returns>
public static DataSet ExecuteDataSet(string commandText, CommandType commandType = CommandType.Text)
{
if (string.IsNullOrEmpty(ConnectionString))
throw new Exception("connectionString");
if (string.IsNullOrEmpty(commandText))
throw new ArgumentNullException("commandText");
var ds = new DataSet();
var con = new SQLiteConnection(ConnectionString);
var cmd = new SQLiteCommand();
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, false, commandType, commandText);
try
{
var sda = new SQLiteDataAdapter(cmd);
sda.Fill(ds);
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
}
return ds;
}

/// <summary>
/// 执行数据库查询,返回DataSet对象
/// </summary>
/// <param name="commandText">执行语句或存储过程名</param>
/// <param name="commandType">执行类型(默认语句)</param>
/// <param name="cmdParms">SQL参数对象</param>
/// <returns>DataSet对象</returns>
public static DataSet ExecuteDataSet(string commandText, CommandType commandType = CommandType.Text, params SQLiteParameter[] cmdParms)
{
if (string.IsNullOrEmpty(ConnectionString))
throw new Exception("connectionString");
if (string.IsNullOrEmpty(commandText))
throw new ArgumentNullException("commandText");
var ds = new DataSet();
var con = new SQLiteConnection(ConnectionString);
var cmd = new SQLiteCommand();
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, false, commandType, commandText, cmdParms);
try
{
var sda = new SQLiteDataAdapter(cmd);
sda.Fill(ds);
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
}
return ds;
}
#endregion

#region 执行数据库查询,返回DataTable对象

/// <summary>
/// 执行数据库查询,返回DataTable对象
/// </summary>
/// <param name="commandText">执行语句或存储过程名</param>
/// <param name="commandType">执行类型(默认语句)</param>
/// <param name="cmdParms"></param>
/// <returns>DataTable对象</returns>
public static DataTable ExecuteDataTable(string commandText, CommandType commandType = CommandType.Text, params SQLiteParameter[] cmdParms)
{
var dt = new DataTable();
var con = new SQLiteConnection(ConnectionString);
var cmd = new SQLiteCommand();
SQLiteTransaction trans = null;
PrepareCommand(cmd, con, ref trans, false, commandType, commandText, cmdParms);
try
{
var sda = new SQLiteDataAdapter(cmd);
sda.Fill(dt);
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
}
return dt;
}

#endregion

#region 通用分页查询方法
/// <summary>
/// 通用分页查询方法
/// </summary>
/// <param name="tableName">表名</param>
/// <param name="strColumns">查询字段名</param>
/// <param name="strWhere">where条件</param>
/// <param name="strOrder">排序条件</param>
/// <param name="pageSize">每页数据数量</param>
/// <param name="currentIndex">当前页数</param>
/// <param name="recordOut">数据总量</param>
/// <returns>DataTable数据表</returns>
public static DataTable SelectPaging(string tableName, string strColumns, string strWhere, string strOrder, int pageSize, int currentIndex, out int recordOut)
{
var dt = new DataTable();
recordOut = Convert.ToInt32(ExecuteScalar("select count(*) from " + tableName));
const string pagingTemplate = "select {0} from {1} where {2} order by {3} limit {4} offset {5} ";
var offsetCount = (currentIndex - 1) * pageSize;
var commandText = String.Format(pagingTemplate, strColumns, tableName, strWhere, strOrder, pageSize, offsetCount);
using (var reader = ExecuteReader(commandText))
{
if (reader != null)
{
dt.Load(reader);
}
}
return dt;
}

#endregion

#region 预处理Command对象,数据库链接,事务,需要执行的对象,参数等的初始化
/// <summary>
/// 预处理Command对象,数据库链接,事务,需要执行的对象,参数等的初始化
/// </summary>
/// <param name="cmd">Command对象</param>
/// <param name="conn">Connection对象</param>
/// <param name="trans">Transcation对象</param>
/// <param name="useTrans">是否使用事务</param>
/// <param name="cmdType">SQL字符串执行类型</param>
/// <param name="cmdText">SQL Text</param>
/// <param name="cmdParms">SQLiteParameters to use in the command</param>
private static void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn, ref SQLiteTransaction trans, bool useTrans, CommandType cmdType, string cmdText, params SQLiteParameter[] cmdParms)
{

if (conn.State != ConnectionState.Open)
conn.Open();

cmd.Connection = conn;
cmd.CommandText = cmdText;

if (useTrans)
{
trans = conn.BeginTransaction(IsolationLevel.ReadCommitted);
cmd.Transaction = trans;
}


cmd.CommandType = cmdType;

if (cmdParms == null) return;
foreach (var parm in cmdParms)
cmd.Parameters.Add(parm);
}

#endregion

}
}

+ 83
- 0
GoChat.Infrastructure/TypeExtensions.cs Datei anzeigen

@@ -0,0 +1,83 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace GoChat.Infrastructure
{
/// <summary>
/// 类型扩展方法类
/// </summary>
public static class TypeExtensions
{
/// <summary>
/// 判断指定类型是否为数值类型
/// </summary>
/// <param name="type">要检查的类型</param>
/// <returns>是否是数值类型</returns>
public static bool IsNumeric(this Type type)
{
return type == typeof (Byte)
|| type == typeof (Int16)
|| type == typeof (Int32)
|| type == typeof (Int64)
|| type == typeof (SByte)
|| type == typeof (UInt16)
|| type == typeof (UInt32)
|| type == typeof (UInt64)
|| type == typeof (Decimal)
|| type == typeof (Double)
|| type == typeof (Single);
}

/// <summary>
/// 获取成员元数据的Description特性描述信息
/// </summary>
/// <param name="member">成员元数据对象</param>
/// <param name="inherit">是否搜索成员的继承链以查找描述特性</param>
/// <returns>返回Description特性描述信息,如不存在则返回成员的名称</returns>
public static string ToDescription(this MemberInfo member, bool inherit = false)
{
DescriptionAttribute desc = member.GetAttribute<DescriptionAttribute>(inherit);
return desc == null ? null : desc.Description;
}

/// <summary>
/// 检查指定指定类型成员中是否存在指定的Attribute特性
/// </summary>
/// <typeparam name="T">要检查的Attribute特性类型</typeparam>
/// <param name="memberInfo">要检查的类型成员</param>
/// <param name="inherit">是否从继承中查找</param>
/// <returns>是否存在</returns>
public static bool AttributeExists<T>(this MemberInfo memberInfo, bool inherit) where T : Attribute
{
return memberInfo.GetCustomAttributes(typeof(T), inherit).Any(m => (m as T) != null);
}

/// <summary>
/// 从类型成员获取指定Attribute特性
/// </summary>
/// <typeparam name="T">Attribute特性类型</typeparam>
/// <param name="memberInfo">类型类型成员</param>
/// <param name="inherit">是否从继承中查找</param>
/// <returns>存在返回第一个,不存在返回null</returns>
public static T GetAttribute<T>(this MemberInfo memberInfo, bool inherit) where T : Attribute
{
return memberInfo.GetCustomAttributes(typeof(T), inherit).SingleOrDefault() as T;
}

/// <summary>
/// 从类型成员获取指定Attribute特性
/// </summary>
/// <typeparam name="T">Attribute特性类型</typeparam>
/// <param name="memberInfo">类型类型成员</param>
/// <param name="inherit">是否从继承中查找</param>
/// <returns>存在返回第一个,不存在返回null</returns>
public static T[] GetAttributes<T>(this MemberInfo memberInfo, bool inherit) where T : Attribute
{
return memberInfo.GetCustomAttributes(typeof(T), inherit).Cast<T>().ToArray();
}

}

}

+ 4
- 0
GoChat.Infrastructure/packages.config Datei anzeigen

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="System.Data.SQLite.Core" version="1.0.105.2" targetFramework="net451" />
</packages>

+ 13
- 0
GoChat.Models/ChageCountEventArgs.cs Datei anzeigen

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GoChat.Models
{
public class ChageCountEventArgs:EventArgs
{
public FileOperationStateEnum OperationState { get; set; }
}
}

+ 21
- 0
GoChat.Models/ChatHistoryModel.cs Datei anzeigen

@@ -0,0 +1,21 @@
namespace GoChat.Models
{
public class ChatHistoryModel
{
public string UserId { get; set; }

public string UserName { get; set; }

public string FriendId { get; set; }

public string FriendName { get; set; }

public string ChatMessage { get; set; }

public string ChatDate { get; set; }

public int IsSender { get; set; }

public string GroupId { get; set; }
}
}

+ 14
- 0
GoChat.Models/ContactType.cs Datei anzeigen

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GoChat.Models
{
public enum ContactType
{
Friend,
Group
}
}

+ 20
- 0
GoChat.Models/Dict.cs Datei anzeigen

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GoChat.Models
{
/// <summary>
/// 字典类
/// </summary>
public class Dict
{
public string ItemName { get; set; }

public string ItemValue { get; set; }

public object AttachObject { get; set; }
}
}

+ 124
- 0
GoChat.Models/Enumerations.cs Datei anzeigen

@@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GoChat.Models
{
/// <summary>
/// 文件类型
/// </summary>
public enum FileType
{
[Description("文件夹")]
Folder,
[Description("文本文件")]
Txt,
[Description("Doc文件")]
Word,
[Description("Excel文件")]
Excel,
[Description("PPT文件")]
PowerPoint,
[Description("PDF文件")]
Pdf,
[Description("图像文件")]
Image,
[Description("声音文件")]
Sound,
[Description("视频文件")]
Video,
[Description("压缩文件")]
Rar,
[Description("压缩文件")]
Zip,
[Description("Exe文件")]
Exe,
[Description("种子文件")]
Torrent,
[Description("未知类型")]
Other
}


[Flags]
public enum FileOperationStateEnum
{
/// <summary>
/// The task has been created. Start state. Can be converted to <see cref="Waiting"/>.
/// </summary>
Created = 0,

/// <summary>
/// The task created, waiting to start. Can be converted to <see cref="Downloading"/> or <see cref="Canceled"/> or <see cref="Paused"/>.
/// </summary>
Waiting = 1,

/// <summary>
/// The task is being downloaded. Can be converted to <see cref="Paused"/> or <see cref="Completed"/> or <see cref="Canceled"/> or <see cref="Faulted"/>.
/// </summary>
Downloading = 2,

/// <summary>
/// The task is Paused. Can be converted to <see cref="Downloading"/> or <see cref="Canceled"/> or <see cref="Waiting"/>.
/// </summary>
Paused = 4,

/// <summary>
/// The task has been completed. End state.
/// </summary>
Completed = 8,

/// <summary>
/// The task has been canceled. End state.
/// </summary>
Canceled = 16,

/// <summary>
/// The task failed. End state.
/// </summary>
Faulted = 32,

Uploading = 64,
Pausing = 128
}

/// <summary>
/// 文件大小单位
/// </summary>
public enum SizeUnitEnum
{
/// <summary>
/// Byte.
/// </summary>
B,

/// <summary>
/// K byte.
/// </summary>
K,

/// <summary>
/// M byte.
/// </summary>
M,

/// <summary>
/// G byte.
/// </summary>
G,

/// <summary>
/// T byte.
/// </summary>
T,

/// <summary>
/// P byte.
/// </summary>
P
}

}

+ 17
- 0
GoChat.Models/FontFamilyList.cs Datei anzeigen

@@ -0,0 +1,17 @@
using System.Collections.ObjectModel;

namespace GoChat.Models
{
public class FontFamilyList : ObservableCollection<string>
{
public FontFamilyList()
{
this.Add("宋体");
this.Add("新宋体");
this.Add("仿宋");
this.Add("楷体");
this.Add("黑体");
this.Add("微软雅黑");
}
}
}

+ 25
- 0
GoChat.Models/FontSizeList.cs Datei anzeigen

@@ -0,0 +1,25 @@
using System.Collections.ObjectModel;

namespace GoChat.Models
{
public class FontSizeList : ObservableCollection<double>
{
public FontSizeList()
{
Add(9);
Add(10);
Add(11);
Add(12);
Add(13);
Add(14);
Add(15);
Add(16);
Add(17);
Add(18);
Add(19);
Add(20);
Add(21);
Add(22);
}
}
}

+ 107
- 0
GoChat.Models/GoChat.Models.csproj Datei anzeigen

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{794481B7-49C5-4E55-912B-D0E61EA2D9A8}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GoChat.Models</RootNamespace>
<AssemblyName>GoChat.Models</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>GoChat.Models</SccProjectName>
<SccLocalPath>1~a7250b02-76e9-4d74-aa27-f5cdf7719296</SccLocalPath>
<SccAuxPath>http://123.57.209.16:8090/VaultService</SccAuxPath>
<SccProvider>SourceGear Vault Visual Studio 2005 Client:{1EA47954-8515-402d-82D9-B5C332120A8D}</SccProvider>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="GalaSoft.MvvmLight, Version=5.3.0.19026, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll</HintPath>
</Reference>
<Reference Include="GalaSoft.MvvmLight.Platform, Version=5.3.0.19032, Culture=neutral, PublicKeyToken=5f873c45e98af8a1, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Platform.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite, Version=1.0.105.2, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\packages\System.Data.SQLite.Core.1.0.105.2\lib\net451\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChageCountEventArgs.cs" />
<Compile Include="ChatHistoryModel.cs" />
<Compile Include="ContactType.cs" />
<Compile Include="Dict.cs" />
<Compile Include="Enumerations.cs" />
<Compile Include="FontFamilyList.cs" />
<Compile Include="FontSizeList.cs" />
<Compile Include="GroupModel.cs" />
<Compile Include="NetDiskFile\BaseFile.cs" />
<Compile Include="NetDiskFile\DownloadNetDiskFile.cs" />
<Compile Include="NetDiskFile\FileHistory.cs" />
<Compile Include="NetDiskFile\IDownload.cs" />
<Compile Include="NetDiskFile\IFile.cs" />
<Compile Include="NetDiskFile\NetDiskFile.cs" />
<Compile Include="NetDiskFile\UploadNetDiskFile.cs" />
<Compile Include="PersonalFontStyle.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SearchFriendOrGroupModel.cs" />
<Compile Include="Skin.cs" />
<Compile Include="UserModel.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="ViewModel\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GoChat.Infrastructure\GoChat.Infrastructure.csproj">
<Project>{71befa2e-3359-4c93-a1bf-4c0e3fc1e905}</Project>
<Name>GoChat.Infrastructure</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\System.Data.SQLite.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\System.Data.SQLite.Core.targets'))" />
</Target>
</Project>

+ 80
- 0
GoChat.Models/GroupModel.cs Datei anzeigen

@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;

namespace GoChat.Models
{
/// <summary>
/// 群组
/// </summary>
public class GroupModel : ObservableObject
{
private string _groupName;
private string _description;
private bool _isReciveGroupMsg;
private string _groupCount;

/// <summary>
/// 群标识
/// </summary>
public string GroupId { get; set; }

/// <summary>
/// 群名称
/// </summary>
public string GroupName
{
get { return _groupName; }
set { _groupName = value; RaisePropertyChanged(() => GroupName); }
}

public int GroupType { get; set; }

public int SortCode { get; set; }

public int Status { get; set; }

/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }

/// <summary>
/// 创建人
/// </summary>
public string CreateName { get; set; }

/// <summary>
/// 群描述
/// </summary>
public string Description
{
get { return _description; }
set { _description = value; RaisePropertyChanged(() => Description); }
}

/// <summary>
/// 群成员
/// </summary>
public ObservableCollection<UserModel> UserModels { get; set; }

public bool IsReciveGroupMsg
{
get { return _isReciveGroupMsg; }
set { _isReciveGroupMsg = value; RaisePropertyChanged(() => IsReciveGroupMsg); }
}

/// <summary>
/// 群成员在线/总数数量
/// </summary>
public string GroupCount
{
get { return _groupCount; }
set { _groupCount = value; RaisePropertyChanged(() => GroupCount); }
}
}
}

+ 188
- 0
GoChat.Models/NetDiskFile/BaseFile.cs Datei anzeigen

@@ -0,0 +1,188 @@
using System;
using System.Collections.ObjectModel;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;

namespace GoChat.Models.NetDiskFile
{
/// <summary>
/// 文件基类
/// </summary>
public class BaseFile : ObservableObject, IFile
{
/// <summary>
/// 文件名称
/// </summary>
public string Name
{
get { return _name; }
set { _name = value;RaisePropertyChanged(); }
}

public string ParentId { get; set; }

/// <summary>
/// 文件Id
/// </summary>
public string FileId { get; set; }

/// <summary>
/// 文件创建时间
/// </summary>
public string CreatedTime { get; set; }

/// <summary>
/// 文件修改时间
/// </summary>
public string ModifiedTime
{
get { return _modifiedTime; }
set { _modifiedTime = value;RaisePropertyChanged(); }
}

/// <summary>
/// 文件类型
/// </summary>
public FileType FileType
{
get { return _fileType; }
set { _fileType = value;RaisePropertyChanged();}
}

/// <summary>
/// Gets or sets the file MD5.
/// </summary>
/// <value>
/// The file MD5.
/// </value>
public string FileMd5 { get; set; }

/// <summary>
/// Gets or sets the local path.
/// </summary>
/// <value>
/// The local path.
/// </value>
public string LocalPath { get; set; }

/// <summary>
/// 字节总数(文件大小)
/// </summary>
public long? TotalBytes
{
get => _totalBytes;
set { _totalBytes = value; RaisePropertyChanged(() => TotalBytes); }
}

/// <summary>
/// 文件地址
/// </summary>
public string FileUrl { get; set; }


public FileOperationStateEnum FileOperationState
{
get { return _fileOperationState; }
set { _fileOperationState = value; RaisePropertyChanged(() => FileOperationState); }
}

/// <summary>
/// 子文件集合
/// </summary>
public ObservableCollection<BaseFile> ChildFiles
{
get => _childFiles ?? new ObservableCollection<BaseFile>();
set { _childFiles = value; RaisePropertyChanged(() => ChildFiles); }
}
private ObservableCollection<BaseFile> _childFiles;
private long? _totalBytes;
private FileOperationStateEnum _fileOperationState;
private string _name;
private string _modifiedTime;
private FileType _fileType;

public async Task GetTotalSize(CancellationToken ct)
{
//HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(FileUrl);
//myHttpWebRequest.Proxy = null;
//var response = await myHttpWebRequest.GetResponseAsync();
//TotalBytes = response.ContentLength;
//response.Close();

HttpClient client = new HttpClient();
var result = await client.GetAsync(new Uri(FileUrl), ct);
if (result.Content.Headers.ContentLength != null) TotalBytes = (long)result.Content.Headers.ContentLength;
client.Dispose();
}

public async Task GetTotalSize()
{
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(FileUrl);
myHttpWebRequest.Proxy = null;
var response = await myHttpWebRequest.GetResponseAsync();
TotalBytes = response.ContentLength;
response.Close();
}

/// <summary>
/// 检测资源链接是否可用
/// </summary>
/// <returns></returns>
public async Task<bool> CheckResource1()
{
try
{
var myHttpWebRequest = (HttpWebRequest)WebRequest.Create(FileUrl);
myHttpWebRequest.Method = "HEAD";
myHttpWebRequest.Proxy = null;
var delay = Task.Delay(10000);
var response = myHttpWebRequest.GetResponseAsync();
bool flag;
if (await Task.WhenAny(response, delay) == delay)
{
flag = false;
}
else
{
var result = await response;
TotalBytes = result.ContentLength;
flag = true;
}
return flag;
}
catch
{
return false;
}
}

/// <summary>
/// 检测资源链接是否可用
/// </summary>
/// <returns></returns>
public async Task<bool> CheckResource()
{
using (var client = new HttpClient())
{
client.Timeout=TimeSpan.FromSeconds(10);
try
{
var result = await client.GetAsync(new Uri(FileUrl), HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
// 确认响应成功,否则抛出异常
result.EnsureSuccessStatusCode();
TotalBytes = result.Content.Headers.ContentLength;
return true;
}
catch(Exception e)
{
return false;
}

}
}
}
}

+ 356
- 0
GoChat.Models/NetDiskFile/DownloadNetDiskFile.cs Datei anzeigen

@@ -0,0 +1,356 @@
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Threading;
using GalaSoft.MvvmLight.CommandWpf;
using GoChat.Infrastructure;

namespace GoChat.Models.NetDiskFile
{
/// <summary>
/// Class DownloadNetDiskFile.
/// </summary>
/// <seealso cref="GoChat.Models.NetDiskFile.NetDiskFile" />
/// <seealso cref="GoChat.Models.NetDiskFile.IDownload" />
public class DownloadNetDiskFile : NetDiskFile
{
#region Fileds and Properties

/// <summary>
/// 计时器
/// </summary>
DispatcherTimer _timer;
private bool _isDownloading;
private long _downloadBytes;
FileStream fs;
private int _progress;
private double _speed;
string _downloadPath;
/// <summary>
/// 用户多线程同步的对象
/// </summary>
readonly object _syncObject = new object();

/// <summary>
/// 用于计算速度的临时变量
/// </summary>
private long _downloadedBytes = 0;

private string _remainingTime = new TimeSpan(0, 0, 0).ToString();


private ObservableCollection<BaseFile> parentCollection;
/// <summary>
/// 已下载的字节数
/// </summary>
public long DownloadBytes
{
get => _downloadBytes;
set { _downloadBytes = value; RaisePropertyChanged(() => DownloadBytes); }
}

/// <summary>
/// 是否正在下载
/// </summary>
public bool IsDownloading
{
get => _isDownloading;
set { _isDownloading = value; RaisePropertyChanged(() => IsDownloading); }
}

/// <summary>
/// 下载剩余时间
/// </summary>
public string RemainingTime
{
get => _remainingTime;
set { _remainingTime = value; RaisePropertyChanged(() => RemainingTime); }
}

/// <summary>
/// 当前进度
/// </summary>
public int Progress
{
get => _progress;
set { _progress = value; RaisePropertyChanged(() => Progress); }
}


/// <summary>
/// 即时速度
/// </summary>
public double Speed
{
get => _speed;
set { _speed = value; RaisePropertyChanged(() => Speed); }
}

/// <summary>
/// 本地路径
/// </summary>
public string LocalPath { get; set; }

public CancellationTokenSource Cts { get; set; }

/// <summary>
/// 暂停下载命令
/// </summary>
public RelayCommand PauseDownloadCommand { get; set; }

/// <summary>
/// 开始下载命令
/// </summary>
public RelayCommand<ProgressBar> StartDownloadCommand { get; set; }

/// <summary>
/// 取消下载命令
/// </summary>
public RelayCommand CancleDownloadCommand { get; set; }

/// <summary>
/// 打开文件命令
/// </summary>
public RelayCommand OpenFileCommand { get; set; }

/// <summary>
/// 打开文件路径命令
/// </summary>
public RelayCommand OpenFilePathCommand { get; set; }


public RelayCommand ClearRecordCommand { get; set; }

/// <summary>
/// 网络响应
/// </summary>
HttpWebResponse _response;


#endregion

public bool IsNewAdd { get; set; }

private string userId;


public DownloadNetDiskFile(ObservableCollection<BaseFile> parent, string id, bool isNew = false)
{
IsNewAdd = isNew;
parentCollection = parent;
userId = id;
PauseDownloadCommand = new RelayCommand(PauseDownload);

StartDownloadCommand = new RelayCommand<ProgressBar>(async (myProgressBar) =>
{
Cts = new CancellationTokenSource();
try
{
await DownloadFileAsync(Cts.Token, new Progress<int>(p => myProgressBar.Value = p));
}
catch
{
FileOperationState = FileOperationStateEnum.Faulted;
}

});

CancleDownloadCommand = new RelayCommand(async () =>
{
FileOperationState = FileOperationStateEnum.Canceled;
if (Cts != null)
{
Cts.Cancel();
}
await FileHistory.DeleteRecord(FileId, userId);
parentCollection.Remove(this);
OnChangeCount(FileOperationState, IsNewAdd);
if (File.Exists(LocalPath))
{
await Task.Run(() =>
{
File.Delete(LocalPath);
});
}
});

ClearRecordCommand = new RelayCommand(async () =>
{
await FileHistory.DeleteRecord(FileId, userId);
parentCollection.Remove(this);
});

OpenFileCommand = new RelayCommand(async () =>
{
try
{
await Task.Run(() => { Process.Start(LocalPath); });
}
catch
{
throw new CommonException("文件不存在,可能已经被移动或者删除");
}

});

OpenFilePathCommand = new RelayCommand(async () =>
{
try
{
await Task.Run(() =>
{
if (File.Exists(LocalPath))
{
Process.Start("explorer.exe", "/select," + LocalPath);
}
else
{
throw new CommonException("目录不存在,可能已经被移动或者删除");
}
});
}
catch
{
throw new CommonException("目录不存在,可能已经被移动或者删除");
}
});

}


public void PauseDownload()
{
FileOperationState = FileOperationStateEnum.Paused;
Speed = 0;
Cts.Cancel();
OnChangeCount(FileOperationState, IsNewAdd);
}

/// <summary>
/// 计算速度及剩余时间
/// </summary>
/// <param name="milliseconds"></param>
public void InitSpeed(int milliseconds)
{
if (FileOperationState == FileOperationStateEnum.Paused || FileOperationState == FileOperationStateEnum.Completed)
{
return;
}
if (milliseconds <= 0) return;
lock (_syncObject)
{
var haveDownloaded = DownloadBytes - _downloadedBytes;
Speed = (haveDownloaded * 1000.0) / milliseconds;
RemainingTime = Math.Abs(Speed) < 0.00001 ? new TimeSpan(0, 0, 0).ToString() : new TimeSpan(0, 0, (int)((TotalBytes - DownloadBytes) / Speed)).ToString();
_downloadedBytes = this.DownloadBytes;
}
}

/// <summary>
/// 下载文件
/// </summary>
/// <param name="url"></param>
/// <param name="ct"></param>
/// <param name="progress"></param>
/// <returns></returns>
public async Task DownloadFileAsync(CancellationToken ct, IProgress<int> progress)
{
try
{
FileOperationState = FileOperationStateEnum.Waiting;
OnChangeCount(FileOperationState, IsNewAdd);
if (!await CheckResource())
{
FileOperationState = FileOperationStateEnum.Faulted;
OnChangeCount(FileOperationState, IsNewAdd);
await FileHistory.UpdateDownloadedState(FileId, this.TotalBytes, null, Progress, FileOperationState, userId);
return;
}
fs = new FileStream(LocalPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
fs.Seek(DownloadBytes, SeekOrigin.Begin);
_timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1000) };
//每秒统计一次速度
_timer.Tick += (s, e) => { InitSpeed(1000); };
_timer.Start();
int bufferSize = 2048;
byte[] bufferBytes = new byte[bufferSize];

var request = (HttpWebRequest)WebRequest.Create(FileUrl);
if (DownloadBytes > 0)
{
request.AddRange(DownloadBytes);
}
_response = (HttpWebResponse)await request.GetResponseAsync();
var responseStream = _response.GetResponseStream();
FileOperationState = FileOperationStateEnum.Downloading;
OnChangeCount(FileOperationState, IsNewAdd);
while (!Cts.IsCancellationRequested)
{
var delay = Task.Delay(10000);
var readAsync = responseStream.ReadAsync(bufferBytes, 0, bufferBytes.Length, ct);
if (await Task.WhenAny(readAsync, delay) == delay)
{
_timer.Stop();
FileOperationState = FileOperationStateEnum.Faulted;
OnChangeCount(FileOperationState, IsNewAdd);
await FileHistory.UpdateDownloadedState(FileId, TotalBytes, DownloadBytes, Progress, FileOperationState, userId);
break;
}
var readSize = await readAsync;
if (readSize > 0)
{
DownloadBytes += readSize;
int percentComplete = (int)((float)DownloadBytes / (float)TotalBytes * 100);
await fs.WriteAsync(bufferBytes, 0, readSize, ct);
Progress = percentComplete;
// 报告进度
progress.Report(percentComplete);
}
else
{
Speed = 0;
FileOperationState = FileOperationStateEnum.Completed;
OnChangeCount(FileOperationState, IsNewAdd);
await FileHistory.UpdateDownloadedState(FileId, TotalBytes, DownloadBytes, Progress, FileOperationState, userId);
_response.Close();
fs.Close();
Progress = 0;
break;
}
}
}
catch (Exception ex)
{
_timer.Stop();
Speed = 0;
FileOperationState = FileOperationStateEnum.Paused;
RemainingTime = new TimeSpan(0, 0, 0).ToString();
_response.Close();
fs.Close();
await FileHistory.UpdateDownloadedState(FileId, TotalBytes, DownloadBytes, Progress, FileOperationState, userId);
}
}




public delegate void ChangeCountEventHandler(object sender, ChageCountEventArgs args, bool isNewAdd);

public event ChangeCountEventHandler ChangeCount;


public void OnChangeCount(FileOperationStateEnum operationState, bool isNewAdd = false)
{
if (ChangeCount != null)
{
ChageCountEventArgs args = new ChageCountEventArgs { OperationState = operationState };
ChangeCount(this, args, isNewAdd);
}
}
}
}

+ 216
- 0
GoChat.Models/NetDiskFile/FileHistory.cs Datei anzeigen

@@ -0,0 +1,216 @@
using System.Data;
using System.Data.SQLite;
using System.Threading.Tasks;
using GoChat.Sqlite;

namespace GoChat.Models.NetDiskFile
{
/// <summary>
///
/// </summary>
public class FileHistory
{

public static Task AddDownloadFileHistory(DownloadNetDiskFile downloadNetDiskFile,string userId)
{
try
{
const string sql = "insert into Tb_DownloadFile (FileId,FileName,FileType,FileUrl,LocalPath,TotalBytes,DownloadedBytes,Progress,DownloadState,UserId) values(@FileId,@FileName,@FileType,@FileUrl,@LocalPath,@TotalBytes,@DownloadedBytes,@Progress,@DownloadState,@UserId)";
if (downloadNetDiskFile.TotalBytes == null)
{
downloadNetDiskFile.TotalBytes = 0;
}
SQLiteParameter[] parameters =
{
SqLiteHelper.MakeSqLiteParameter("@FileId", DbType.String, downloadNetDiskFile.FileId),
SqLiteHelper.MakeSqLiteParameter("@FileName", DbType.String, downloadNetDiskFile.Name),
SqLiteHelper.MakeSqLiteParameter("@FileType", DbType.String, downloadNetDiskFile.FileType.ToString()),
SqLiteHelper.MakeSqLiteParameter("@FileUrl", DbType.String, downloadNetDiskFile.FileUrl),
SqLiteHelper.MakeSqLiteParameter("@LocalPath", DbType.String, downloadNetDiskFile.LocalPath),
SqLiteHelper.MakeSqLiteParameter("@TotalBytes", DbType.Int64,downloadNetDiskFile.TotalBytes),
SqLiteHelper.MakeSqLiteParameter("@DownloadedBytes", DbType.Int64,downloadNetDiskFile.DownloadBytes),
SqLiteHelper.MakeSqLiteParameter("@Progress", DbType.Int32,downloadNetDiskFile.Progress),
SqLiteHelper.MakeSqLiteParameter("@DownloadState", DbType.String,downloadNetDiskFile.FileOperationState.ToString()),
SqLiteHelper.MakeSqLiteParameter("@UserId", DbType.String, userId)
};

var result = Task.Run(() =>
{
var aa = SqLiteHelper.ExecuteNonQuery(sql, cmdParms: parameters);
return aa > 0;
});
return result;
}
catch { return Task.FromResult(false); }
}

/// <summary>
/// 上传文件记录
/// Adds the upload file history.
/// </summary>
/// <param name="uploadNetDiskFile">The upload net disk file.文件信息</param>
/// <param name="userId">The user identifier.用户Id</param>
/// <returns></returns>
public static Task AddUploadFileHistory(UploadNetDiskFile uploadNetDiskFile,string userId)
{
try
{
const string sql = "insert into Tb_DownloadFile (FileId,FileName,FileType,FileUrl,LocalPath,TotalBytes,DownloadedBytes,Progress,DownloadState,Type,CurrentParentId,UserId) values(@FileId,@FileName,@FileType,@FileUrl,@LocalPath,@TotalBytes,@DownloadedBytes,@Progress,@DownloadState,@Type,@CurrentParentId,@UserId)";
if (uploadNetDiskFile.TotalBytes == null)
{
uploadNetDiskFile.TotalBytes = 0;
}
SQLiteParameter[] parameters =
{
SqLiteHelper.MakeSqLiteParameter("@FileId", DbType.String, uploadNetDiskFile.FileId),
SqLiteHelper.MakeSqLiteParameter("@FileName", DbType.String, uploadNetDiskFile.Name),
SqLiteHelper.MakeSqLiteParameter("@FileType", DbType.String, uploadNetDiskFile.FileType.ToString()),
SqLiteHelper.MakeSqLiteParameter("@FileUrl", DbType.String, uploadNetDiskFile.FileUrl),
SqLiteHelper.MakeSqLiteParameter("@LocalPath", DbType.String, uploadNetDiskFile.LocalPath),
SqLiteHelper.MakeSqLiteParameter("@TotalBytes", DbType.Int64,uploadNetDiskFile.TotalBytes),
SqLiteHelper.MakeSqLiteParameter("@DownloadedBytes", DbType.Int64,uploadNetDiskFile.UploadBytes),
SqLiteHelper.MakeSqLiteParameter("@Progress", DbType.Int32,uploadNetDiskFile.Progress),
SqLiteHelper.MakeSqLiteParameter("@DownloadState", DbType.String,uploadNetDiskFile.FileOperationState.ToString()),
SqLiteHelper.MakeSqLiteParameter("@Type", DbType.Int32,1),
SqLiteHelper.MakeSqLiteParameter("@CurrentParentId", DbType.String,uploadNetDiskFile.CurrentParentId),
SqLiteHelper.MakeSqLiteParameter("@UserId", DbType.String,userId)
};

var result = Task.Run(() =>
{
var aa = SqLiteHelper.ExecuteNonQuery(sql, cmdParms: parameters);
return aa > 0;
});
return result;
}
catch { return Task.FromResult(false); }
}

/// <summary>
/// Updates the state of the downloaded.
/// </summary>
/// <param name="fileId">The file identifier.</param>
/// <param name="totalBytes">The total bytes.</param>
/// <param name="downloadedBytes">The downloaded bytes.</param>
/// <param name="percent">The percent.</param>
/// <param name="downloadState">State of the download.</param>
/// <returns></returns>
public static Task UpdateDownloadedState(string fileId, long? totalBytes, long? downloadedBytes, int percent, FileOperationStateEnum downloadState,string userId)
{
try
{
var sql = downloadedBytes != null ? $"update Tb_DownloadFile set TotalBytes={totalBytes}, DownloadedBytes={downloadedBytes},Progress={percent},DownloadState='{downloadState}' where FileId='{fileId}' and UserId='{userId}'" : $"update Tb_DownloadFile set TotalBytes={totalBytes}, Progress={percent},DownloadState='{downloadState}' where FileId='{fileId}' and UserId='{userId}'";

var result = Task.Run(() =>
{
var aa = SqLiteHelper.ExecuteNonQuery(sql);
return aa > 0;
});
return result;
}
catch { return Task.FromResult(false); }
}

public static Task UpdateUploadedState(UploadNetDiskFile uploadNetDiskFile, string userId)
{
try
{
var sql = $"update Tb_DownloadFile set TotalBytes={uploadNetDiskFile.TotalBytes}, DownloadedBytes={uploadNetDiskFile.UploadBytes},Progress={uploadNetDiskFile.Progress},DownloadState='{uploadNetDiskFile.FileOperationState}' where FileId='{uploadNetDiskFile.FileId}' and UserId='{userId}'" ;

var result = Task.Run(() =>
{
var aa = SqLiteHelper.ExecuteNonQuery(sql);
return aa > 0;
});
return result;
}
catch { return Task.FromResult(false); }
}

public static async Task<bool> DeleteRecord(string fileId,string userId)
{
const string sql = "delete from Tb_DownloadFile where FileId=@FileId and UserId=@UserId and Type=0";
SQLiteParameter[] parameters =
{
SqLiteHelper.MakeSqLiteParameter("@FileId", DbType.String, fileId),
SqLiteHelper.MakeSqLiteParameter("@UserId", DbType.String, userId)
};
try
{
var result = await Task.Run(() => SqLiteHelper.ExecuteNonQuery(sql, cmdParms: parameters));
return result > 0;
}
catch
{
return false;
}
}

public static async Task<bool> DeleteUploadRecord(string fileId, string userId)
{
const string sql = "delete from Tb_DownloadFile where FileId=@FileId and UserId=@UserId and Type=1";
SQLiteParameter[] parameters =
{
SqLiteHelper.MakeSqLiteParameter("@FileId", DbType.String, fileId),
SqLiteHelper.MakeSqLiteParameter("@UserId", DbType.String, userId)
};
try
{
var result = await Task.Run(() => SqLiteHelper.ExecuteNonQuery(sql, cmdParms: parameters));
return result > 0;
}
catch
{
return false;
}
}

public static async Task<DataTable> GetDownloadFileList(string userId)
{
//string sql = $"select FileId,FileName,FileType,FileUrl,LocalPath,TotalBytes,DownloadedBytes,Progress,DownloadState from Tb_DownloadFile where Type=0 and UserId='{userId}'";
string sql = $"select FileId,FileName,FileType,FileUrl,LocalPath,TotalBytes,DownloadedBytes,Progress,DownloadState from Tb_DownloadFile where Type=0 and UserId='{userId}'";
try
{
var data = await Task.Run(() => SqLiteHelper.ExecuteDataTable(sql));
return data;
}
catch
{
return null;
}
}

public static async Task<DataTable> GetUploadFileList()
{
const string sql = "select FileId,FileName,FileType,FileUrl,LocalPath,TotalBytes,DownloadedBytes,Progress,DownloadState,UserId from Tb_DownloadFile where Type=1";
try
{
var data = await Task.Run(() => SqLiteHelper.ExecuteDataTable(sql));
return data;
}
catch
{
return null;
}
}

public static async Task<string> GetFileInfo(string fileid)
{
const string sql = "select * from Tb_DownloadFile where FileId=@FileId";
SQLiteParameter[] parameters =
{
SqLiteHelper.MakeSqLiteParameter("@FileId", DbType.String, fileid)
};
try
{
var data = await Task.Run(() => SqLiteHelper.ExecuteScalar(sql, cmdParms: parameters));
return data.ToString();
}
catch
{
return null;
}
}

}
}

+ 11
- 0
GoChat.Models/NetDiskFile/IDownload.cs Datei anzeigen

@@ -0,0 +1,11 @@
using System;
using System.Threading;
using System.Threading.Tasks;

namespace GoChat.Models.NetDiskFile
{
public interface IDownload:IFile
{
Task DownloadFileAsync(string url, CancellationToken ct, IProgress<int> progress);
}
}

+ 9
- 0
GoChat.Models/NetDiskFile/IFile.cs Datei anzeigen

@@ -0,0 +1,9 @@
using System.Threading.Tasks;

namespace GoChat.Models.NetDiskFile
{
public interface IFile
{
Task GetTotalSize();
}
}

+ 44
- 0
GoChat.Models/NetDiskFile/NetDiskFile.cs Datei anzeigen

@@ -0,0 +1,44 @@
namespace GoChat.Models.NetDiskFile
{
/// <summary>
/// 网盘文件类
/// </summary>
public class NetDiskFile : BaseFile
{
//#region Properties

///// <summary>
///// 文件名称
///// </summary>
//public new string Name
//{
// get => _name;
// set { _name = value; RaisePropertyChanged(()=> Name);}
//}

///// <summary>
///// 文件修改时间
///// </summary>
//public new string ModifiedTime
//{
// get => _modifiedTime1;
// set { _modifiedTime1 = value; RaisePropertyChanged(() => ModifiedTime); }
//}

///// <summary>
///// 文件类型
///// </summary>
//public new FileType FileType
//{
// get => _fileType1;
// set { _fileType1 = value; RaisePropertyChanged(() => FileType); }
//}

//private string _name;
//private string _modifiedTime1;
//private FileType _fileType1;

//#endregion
}
}

+ 391
- 0
GoChat.Models/NetDiskFile/UploadNetDiskFile.cs Datei anzeigen

@@ -0,0 +1,391 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using GalaSoft.MvvmLight.CommandWpf;
using Newtonsoft.Json;

namespace GoChat.Models.NetDiskFile
{
/// <summary>
/// 上传文件类
/// </summary>
/// <seealso cref="GoChat.Models.NetDiskFile.NetDiskFile" />
public class UploadNetDiskFile : NetDiskFile
{
private long _uploadBytes;
private bool _isUploading;
private string _remainingTime;
private int _progress;
private double _speed;

#region Properties

/// <summary>
/// Gets or sets the upload bytes.
/// </summary>
/// <value>The upload bytes.</value>
public long UploadBytes
{
get { return _uploadBytes; }
set { _uploadBytes = value; RaisePropertyChanged(); }
}

public bool IsUploading
{
get { return _isUploading; }
set { _isUploading = value; RaisePropertyChanged(); }
}

public string RemainingTime
{
get { return _remainingTime; }
set { _remainingTime = value; RaisePropertyChanged(); }
}

public int Progress
{
get { return _progress; }
set { _progress = value; RaisePropertyChanged(); }
}

public double Speed
{
get { return _speed; }
set { _speed = value; RaisePropertyChanged(); }
}

public string CurrentParentId { get; set; }

public CancellationTokenSource Cts { get; set; }

/// <summary>
/// 暂停上传命令
/// </summary>
public RelayCommand PauseUploadCommand { get; set; }

/// <summary>
/// 开始上传命令
/// </summary>
public RelayCommand<dynamic> StartUpload { get; set; }


/// <summary>
/// 取消上传命令
/// </summary>
public RelayCommand<ObservableCollection<BaseFile>> CancleUploadCommand { get; set; }


/// <summary>
/// 打开文件路径命令
/// </summary>
public RelayCommand OpenFilePathCommand { get; set; }


private ObservableCollection<BaseFile> parentCollection;

private readonly string _currentUserId;

#endregion

/// <summary>
/// Initializes a new instance of the <see cref="UploadNetDiskFile"/> class.
/// </summary>
/// <param name="parent">当前数据源</param>
/// <param name="userId">当前用户Id</param>
/// <param name="parentId"></param>
public UploadNetDiskFile(ObservableCollection<BaseFile> parent = null, string userId = null, string parentId = null)
{
parentCollection = parent;
_currentUserId = userId;
CurrentParentId = parentId;

//取消上传
CancleUploadCommand = new RelayCommand<ObservableCollection<BaseFile>>(async (arr) =>
{
if (Cts != null)
{
Cts.Cancel();
}
FileOperationState = FileOperationStateEnum.Canceled;
await FileHistory.DeleteUploadRecord(FileId, _currentUserId);
arr.Remove(this);
});

StartUpload = new RelayCommand<dynamic>(async (obj) =>
{
Cts = new CancellationTokenSource();
var uploadResult = await UpLoadFileAsync(this, new Progress<int>(p => obj[0].Value = p));
if (uploadResult.result)
{
var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
using (var client = new HttpClient(handler))
{
var requestJson = JsonConvert.SerializeObject(
new
{
FileName = Name,
FileSaveName = FileMd5,
FolderId = CurrentParentId,
UserId = _currentUserId,
FileType = (int)FileType,
FileSize = TotalBytes.ToString(),
ExtendName = Path.GetExtension(Name),
FileUrl = $"~/Resource/DocumentFile/{_currentUserId}/{ DateTime.Now:yyyyMMdd}/{FileMd5}{Path.GetExtension(Name)}"
});
HttpContent httpContent = new StringContent(requestJson, Encoding.UTF8, "application/json");
var response = await client.PostAsync(FileUrl + "api/savefile", httpContent);
response.EnsureSuccessStatusCode();
obj[1].Remove(this);
}
}

});

//暂停上传
PauseUploadCommand = new RelayCommand(() =>
{
FileOperationState = FileOperationStateEnum.Pausing;
Cts.Cancel();

});

}

private async void Test()
{
FileOperationState = FileOperationStateEnum.Canceled;
if (Cts != null)
{
Cts.Cancel();
}
await FileHistory.DeleteUploadRecord(FileId, _currentUserId);
}


/// <summary>
/// 根据文件名获取是否是续传和续传的下次开始节点
/// </summary>
/// <param name="md5str"></param>
/// <param name="fileextname"></param>
/// <returns></returns>
private async Task<long> GetStartPoint(string md5str, string fileextname)
{
HttpClient client = new HttpClient();
try
{
var webmain = await client.GetStringAsync(FileUrl + "api/getmainserver");
var objwebmain = JsonConvert.DeserializeObject<dynamic>(webmain);
var url = objwebmain.resultdata.ToString() + "/Login/GetResumFile?md5str=" + md5str + fileextname + "&uid=" + _currentUserId;
var response = await client.GetStringAsync(url);
//正则替换
string jstring = response.Replace("\"", "");
var result = 0;
int.TryParse(jstring, out result);
return result;
}
catch (Exception e)
{
return 0;
}
}

/// <summary>
/// 文件MD5
/// Gets the stream MD5.
/// </summary>
/// <param name="stream">The stream.</param>
/// <returns></returns>
public static string GetStreamMd5(Stream stream)
{
var oMd5Hasher = new MD5CryptoServiceProvider();
byte[] arrbytHashValue = oMd5Hasher.ComputeHash(stream);
//由以连字符分隔的十六进制对构成的String,其中每一对表示value 中对应的元素;例如“F-2C-4A”
string strHashData = BitConverter.ToString(arrbytHashValue);
//替换-
strHashData = strHashData.Replace("-", "");
string strResult = strHashData;
return strResult;
}

#region MyRegion

System.Timers.Timer _timer;
/// <summary>
/// 用户多线程同步的对象
/// </summary>
readonly object _syncObject = new object();
/// <summary>
/// 用于计算速度的临时变量
/// </summary>
private long _uploadedBytes = 0;
/// <summary>
/// 计算速度及剩余时间
/// </summary>
/// <param name="milliseconds"></param>
public void InitSpeed(int milliseconds)
{
if (FileOperationState == FileOperationStateEnum.Paused || FileOperationState == FileOperationStateEnum.Completed)
{
return;
}
if (milliseconds <= 0) return;
lock (_syncObject)
{
var haveDownloaded = UploadBytes - _uploadedBytes;
Speed = (haveDownloaded * 1000.0) / milliseconds;
RemainingTime = Math.Abs(Speed) < 0.00001 ? new TimeSpan(0, 0, 0).ToString() : new TimeSpan(0, 0, (int)((TotalBytes - UploadBytes) / Speed)).ToString();
_uploadedBytes = this.UploadBytes;
}
}



public async Task<dynamic> UpLoadFileAsync(UploadNetDiskFile model, IProgress<int> progress)
{
FileOperationState = FileOperationStateEnum.Waiting;
var result = await Task.Run(async () =>
{
FileStream fStream = new FileStream(model.LocalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
FileMd5 = GetStreamMd5(fStream);
TotalBytes = fStream.Length;
fStream.Close();
UploadBytes = await GetStartPoint(FileMd5, Path.GetExtension(model.LocalPath));
HttpClient client = new HttpClient();
var webmain = await client.GetStringAsync(model.FileUrl + "api/getmainserver");
var objwebmain = JsonConvert.DeserializeObject<dynamic>(webmain);
var uploadFileResult = await UpLoadFile(model.LocalPath, objwebmain.resultdata.ToString() + "/Login/Rsume", 100, UploadBytes, FileMd5, model.Cts.Token, progress);
return new { result = uploadFileResult, md5 = FileMd5 };
}, model.Cts.Token);
return result;
}

/// <summary>
/// 上传文件(自动分割)
/// </summary>
/// <param name="filePath">待上传的文件全路径名称</param>
/// <param name="hostURL">服务器的地址</param>
/// <param name="byteCount">分割的字节大小</param>
/// <param name="cruuent">当前字节指针</param>
/// <returns>成功返回"";失败则返回错误信息</returns>
public async Task<bool> UpLoadFile(string filePath, string hostURL, int byteCount, long cruuent, string mdfstr, CancellationToken ct, IProgress<int> progress)
{
bool result = false;
string tmpURL = hostURL;
byteCount = byteCount * 1024;
WebClient webClientObj = new WebClient();
FileStream fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
BinaryReader bReader = new BinaryReader(fStream);
TotalBytes = fStream.Length;
string fileName = filePath.Substring(filePath.LastIndexOf('\\') + 1);
_timer = new System.Timers.Timer(1000);

//每秒统计一次速度
_timer.Elapsed += (s, e) => { InitSpeed(1000); };
_timer.AutoReset = true;
_timer.Enabled = true;
_timer.Start();
FileOperationState = FileOperationStateEnum.Uploading;
try
{

#region 续传处理
byte[] data;
if (cruuent > 0)
{
fStream.Seek(cruuent, SeekOrigin.Current);
}
#endregion

#region 分割文件上传
for (; cruuent <= TotalBytes; cruuent = cruuent + byteCount)
{
if (!ct.IsCancellationRequested)
{
if (cruuent + byteCount > TotalBytes)
{
data = new byte[Convert.ToInt64((TotalBytes - cruuent))];
bReader.Read(data, 0, Convert.ToInt32((TotalBytes - cruuent)));
}
else
{
data = new byte[byteCount];
bReader.Read(data, 0, byteCount);
}

try
{
webClientObj.Headers.Remove(HttpRequestHeader.ContentRange);
webClientObj.Headers.Add(HttpRequestHeader.ContentRange, "bytes " + cruuent + "-" + (cruuent + byteCount) + "/" + fStream.Length);
hostURL = tmpURL + "?filename=" + mdfstr + Path.GetExtension(fileName) + "&uid=" + _currentUserId;
await webClientObj.UploadDataTaskAsync(hostURL, "POST", data);
UploadBytes = cruuent;
int percentComplete = (int)((float)cruuent / (float)TotalBytes * 100);
if (cruuent + byteCount > TotalBytes)
{
percentComplete = 100;
Progress = percentComplete;
// 报告进度
progress.Report(percentComplete);
UploadBytes = (long)TotalBytes;
FileOperationState = FileOperationStateEnum.Completed;
await FileHistory.DeleteUploadRecord(FileId, _currentUserId);
result = true;
}
else
{
Progress = percentComplete;
// 报告进度
progress.Report(percentComplete);
}

}
catch (Exception e)
{
break;
}
}
else
{
_timer.Stop();
_timer.Dispose();
result = false;
FileOperationState = FileOperationStateEnum.Paused;
await FileHistory.UpdateUploadedState(this, _currentUserId);
break;
}
#endregion

}
}
catch (Exception ex)
{

}
try
{
bReader.Close();
fStream.Close();
}
catch (Exception exMsg)
{

}
//GC.Collect();
return result;
//return sMsg;
}

#endregion


}
}

+ 45
- 0
GoChat.Models/PersonalFontStyle.cs Datei anzeigen

@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GoChat.Models
{
/// <summary>
/// 个人文本样式
/// </summary>
[Serializable]
public class PersonalFontStyle
{
/// <summary>
/// 文本字体
/// </summary>
public string TextFontFamliy { get; set; }

/// <summary>
/// 文本字体大小
/// </summary>
public string TextFontSize { get; set; }

/// <summary>
/// 文本是否加粗
/// </summary>
public bool TextBlod { get; set; }

/// <summary>
/// 文本是否倾斜
/// </summary>
public bool TextItalic { get; set; }

/// <summary>
/// 文本是否有下划线
/// </summary>
public bool TextUnderline { get; set; }

/// <summary>
/// 文本颜色
/// </summary>
public string TextColor { get; set; }
}
}

+ 37
- 0
GoChat.Models/Properties/AssemblyInfo.cs Datei anzeigen

@@ -0,0 +1,37 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("GoChat.Models")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GoChat.Models")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: InternalsVisibleTo("GoChat.Win")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("794481b7-49c5-4e55-912b-d0e61ea2d9a8")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

+ 64
- 0
GoChat.Models/SearchFriendOrGroupModel.cs Datei anzeigen

@@ -0,0 +1,64 @@
using GalaSoft.MvvmLight;

namespace GoChat.Models
{
public class SearchFriendOrGroupModel : ObservableObject
{
private string _searchType;
private string _name;
private string _id;
private int _onlineState;

/// <summary>
/// 搜索分组类型
/// </summary>
public string SearchType
{
get { return _searchType; }
set { _searchType = value; RaisePropertyChanged(() => SearchType); }
}

/// <summary>
/// 好友或者群名称
/// </summary>
public string Name
{
get { return _name; }
set { _name = value; RaisePropertyChanged(() => Name); }
}

public bool IsUpdateHead
{
get { return _isUpdateHead; }
set { _isUpdateHead = value; RaisePropertyChanged(() => IsUpdateHead); }
}

/// <summary>
/// 好友或者群Id
/// </summary>
public string Id
{
get { return _id; }
set { _id = value; RaisePropertyChanged(() => Id); }
}
private string _headIcon;
private bool _isUpdateHead;

/// <summary>
/// 头像
/// </summary>
public string HeadIcon
{
get { return _headIcon; }
set { _headIcon = value; RaisePropertyChanged(() => HeadIcon); }
}

public int OnlineState
{
get { return _onlineState; }
set { _onlineState = value; RaisePropertyChanged(() => OnlineState); }
}

public string CurrentDate { get; set; }
}
}

+ 39
- 0
GoChat.Models/Skin.cs Datei anzeigen

@@ -0,0 +1,39 @@
using System;

namespace GoChat.Models
{
/// <summary>
/// 皮肤
/// </summary>
[Serializable]
public class Skin
{
public Skin()
{
IsGif = false;
}
public object WinBrush { get; set; }

/// <summary>
/// 是否动画皮肤
/// </summary>
public bool IsGif { get; set; }

/// <summary>
/// 动画皮肤地址
/// </summary>
public Uri GifUri { get; set; }

/// <summary>
/// 是否图片皮肤
/// </summary>
public bool IsImg { get; set; }

/// <summary>
/// 图片地址
/// </summary>
public object ImgSrc { get; set; }
public bool IsPureColor { get; set; }

}
}

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.

Laden…
Abbrechen
Speichern