| @@ -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> | |||
| @@ -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> | |||
| @@ -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; } | |||
| } | |||
| } | |||
| @@ -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")] | |||
| @@ -0,0 +1,4 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <packages> | |||
| <package id="Newtonsoft.Json" version="6.0.1" targetFramework="net452" /> | |||
| </packages> | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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; } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| @@ -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> | |||
| @@ -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); } | |||
| } | |||
| } | |||
| } | |||
| @@ -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); } | |||
| } | |||
| } | |||
| } | |||
| @@ -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); } | |||
| } | |||
| } | |||
| } | |||
| @@ -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); } | |||
| } | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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")] | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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> | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,7 @@ | |||
| <?xml version='1.0' encoding='utf-8'?> | |||
| <SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> | |||
| <Profiles> | |||
| <Profile Name="(Default)" /> | |||
| </Profiles> | |||
| <Settings /> | |||
| </SettingsFile> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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))); | |||
| } | |||
| } | |||
| } | |||
| @@ -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> | |||
| @@ -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="" | |||
| 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> | |||
| @@ -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> | |||
| @@ -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="" 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="" 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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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="" 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="" /> | |||
| </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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,4 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <packages> | |||
| <package id="XamlAnimatedGif" version="1.1.10" targetFramework="net451" /> | |||
| </packages> | |||
| @@ -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) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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> | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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) | |||
| { | |||
| } | |||
| } | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| @@ -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")] | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| } | |||
| @@ -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> | |||
| @@ -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; } | |||
| } | |||
| } | |||
| @@ -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; } | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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; } | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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("微软雅黑"); | |||
| } | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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> | |||
| @@ -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); } | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| @@ -0,0 +1,9 @@ | |||
| using System.Threading.Tasks; | |||
| namespace GoChat.Models.NetDiskFile | |||
| { | |||
| public interface IFile | |||
| { | |||
| Task GetTotalSize(); | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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; } | |||
| } | |||
| } | |||
| @@ -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")] | |||
| @@ -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; } | |||
| } | |||
| } | |||
| @@ -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; } | |||
| } | |||
| } | |||