功能更新
This commit is contained in:
@@ -1,16 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
|
||||||
<OutputType>WinExe</OutputType>
|
|
||||||
<LangVersion>13.0</LangVersion>
|
|
||||||
<UseWPF>true</UseWPF>
|
|
||||||
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
|
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\NeoUI\Melskin\Melskin.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
20
KeyGen/App.xaml
Normal file
20
KeyGen/App.xaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<Application
|
||||||
|
StartupUri="MainWindow.xaml"
|
||||||
|
x:Class="KeyGen.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:local="clr-namespace:KeyGen"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Application.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<!--<ms:ThemesDictionary Mode="Dark" Palette="Blue"/>
|
||||||
|
<ms:ControlsDictionary/>-->
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/Melskin;component/Themes/Light.xaml" />
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/Melskin;component/Themes/Accents/LightBlue.xaml" />
|
||||||
|
<!--<ResourceDictionary Source="pack://application:,,,/NeoUI;component/Themes/ColorPalette/DarkBlue.xaml"/>
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/NeoUI;component/Themes/Dark.xaml" />-->
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/Melskin;component/Themes/Generic.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</Application.Resources>
|
||||||
|
</Application>
|
||||||
12
KeyGen/App.xaml.cs
Normal file
12
KeyGen/App.xaml.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System.Configuration;
|
||||||
|
using System.Data;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace KeyGen;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for App.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class App : Application
|
||||||
|
{
|
||||||
|
}
|
||||||
10
KeyGen/AssemblyInfo.cs
Normal file
10
KeyGen/AssemblyInfo.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
[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)
|
||||||
|
)]
|
||||||
20
KeyGen/KeyGen.csproj
Normal file
20
KeyGen/KeyGen.csproj
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net48</TargetFramework>
|
||||||
|
<LangVersion>preview</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<UseWPF>true</UseWPF>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Melskin\Melskin.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System.Management" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
using System.Text;
|
using System.Reflection;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
namespace KeyGen
|
namespace KeyGen
|
||||||
{
|
{
|
||||||
|
|||||||
42
KeyGen/MainWindow.xaml
Normal file
42
KeyGen/MainWindow.xaml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<ms:MelWindow
|
||||||
|
Height="450"
|
||||||
|
Title="MainWindow"
|
||||||
|
Width="800"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
x:Class="KeyGen.MainWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:KeyGen"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:ms="https://github.com/ShrlAlgo/Melskin"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Grid>
|
||||||
|
<ms:StackPanel HorizontalAlignment="Center" Width="600">
|
||||||
|
<UniformGrid Rows="1">
|
||||||
|
<TextBox ms:InputAssist.Prefix="私钥:" x:Name="PrivateKeyTextBox" />
|
||||||
|
<TextBox ms:InputAssist.Prefix="公钥:" x:Name="PublicKeyTextBox" />
|
||||||
|
<Button Click="GenerateKeyClick" Content="计算公私密钥" />
|
||||||
|
<Button Click="SaveKeysClick" Content="保存公、私密钥" />
|
||||||
|
</UniformGrid>
|
||||||
|
<UniformGrid>
|
||||||
|
<TextBox ms:InputAssist.Prefix="机器码:" x:Name="MachineCodeTextBox" />
|
||||||
|
<Button Click="MachineCodeClick" Content="获取本机机器码" />
|
||||||
|
<ms:FlexibleRowPanel LayoutMode="Auto">
|
||||||
|
<TextBlock Text="授权到期日期:" VerticalAlignment="Center" />
|
||||||
|
<DatePicker ms:FlexibleRowPanel.IsFill="True" x:Name="ExpiryDatePicker" />
|
||||||
|
</ms:FlexibleRowPanel>
|
||||||
|
<Button Click="LicenseClick" Content="获取激活码" />
|
||||||
|
</UniformGrid>
|
||||||
|
|
||||||
|
<UniformGrid Rows="1">
|
||||||
|
<TextBox ms:InputAssist.Prefix="激活码:" x:Name="LicenseTextBox" />
|
||||||
|
<Button Click="ActivateClick" Content="激活授权" />
|
||||||
|
<Button Click="SaveLicenseClick" Content="保存激活码" />
|
||||||
|
</UniformGrid>
|
||||||
|
<UniformGrid Rows="1">
|
||||||
|
<Button Click="ValidateClick" Content="授权验证" />
|
||||||
|
<Button Click="RemoveLicenseClick" Content="移除授权" />
|
||||||
|
</UniformGrid>
|
||||||
|
</ms:StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ms:MelWindow>
|
||||||
168
KeyGen/MainWindow.xaml.cs
Normal file
168
KeyGen/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Management;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
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 Melskin.Controls;
|
||||||
|
|
||||||
|
namespace KeyGen;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MainWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class MainWindow
|
||||||
|
{
|
||||||
|
private static string _privateKey = string.Empty;
|
||||||
|
public MainWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
private void LicenseClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
_privateKey = PrivateKeyTextBox.Text;
|
||||||
|
LicenseManager.PublicKey = PublicKeyTextBox.Text;
|
||||||
|
DateTime issueDate = DateTime.Now;
|
||||||
|
//DateTime expiryDate = issueDate.AddYears(1);
|
||||||
|
DateTime expiryDate = ExpiryDatePicker.DisplayDate;
|
||||||
|
if (expiryDate < issueDate)
|
||||||
|
{
|
||||||
|
MessageBox.Show("授权到期时间有误,应比发码日期晚");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string mCode = MachineCodeTextBox.Text.Trim().ToUpper();
|
||||||
|
if (string.IsNullOrEmpty(mCode))
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先获取机器码");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string key = CreateLicense(mCode, issueDate, expiryDate);
|
||||||
|
LicenseTextBox.Text = key;
|
||||||
|
Clipboard.SetText(key);
|
||||||
|
MessageBox.Show("激活码已复制!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CreateLicense(string machineCode, DateTime issue, DateTime expiry)
|
||||||
|
{
|
||||||
|
string issueStr = issue.ToString("yyyyMMdd");
|
||||||
|
string expiryStr = expiry.ToString("yyyyMMdd");
|
||||||
|
|
||||||
|
// 签名原始数据:机器码 + 发码日期 + 过期日期
|
||||||
|
string dataToSign = $"{machineCode}|{issueStr}|{expiryStr}";
|
||||||
|
|
||||||
|
using (var rsa = new RSACryptoServiceProvider())
|
||||||
|
{
|
||||||
|
rsa.FromXmlString(_privateKey);
|
||||||
|
var formatter = new RSAPKCS1SignatureFormatter(rsa);
|
||||||
|
formatter.SetHashAlgorithm("SHA256");
|
||||||
|
|
||||||
|
byte[] dataBytes = Encoding.UTF8.GetBytes(dataToSign);
|
||||||
|
using (var sha = SHA256.Create())
|
||||||
|
{
|
||||||
|
byte[] hash = sha.ComputeHash(dataBytes);
|
||||||
|
string signature = Convert.ToBase64String(formatter.CreateSignature(hash));
|
||||||
|
|
||||||
|
// 最终格式:签名|机器码|发码日期|过期日期
|
||||||
|
return $"{signature}|{machineCode}|{issueStr}|{expiryStr}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateKeyClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
using var rsa = new RSACryptoServiceProvider(2048);
|
||||||
|
PublicKeyTextBox.Text = rsa.ToXmlString(false); // 放在插件里
|
||||||
|
PrivateKeyTextBox.Text = rsa.ToXmlString(true); // 自己妥善保存
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ValidateClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var result = LicenseManager.Validate();
|
||||||
|
MessageBox.Show(result.msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveLicenseClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
LicenseManager.RemoveLicense();
|
||||||
|
MessageBox.Show("授权已注销");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ActivateClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
LicenseManager.Activate(LicenseTextBox.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MachineCodeClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
MachineCodeTextBox.Text = HardwareInfo.GetMachineCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveKeysClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog();
|
||||||
|
if (dialog.ShowDialog())
|
||||||
|
{
|
||||||
|
string publicKeyPath = System.IO.Path.Combine(dialog.SelectedPath, "PublicKey.txt");
|
||||||
|
File.WriteAllText(publicKeyPath, PublicKeyTextBox.Text);
|
||||||
|
string privateKeyPath = System.IO.Path.Combine(dialog.SelectedPath, "PrivateKey.txt");
|
||||||
|
File.WriteAllText(privateKeyPath, PrivateKeyTextBox.Text);
|
||||||
|
MessageBox.Show($"公私密钥已保存到:{dialog.SelectedPath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveLicenseClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog();
|
||||||
|
if (dialog.ShowDialog())
|
||||||
|
{
|
||||||
|
string path = System.IO.Path.Combine(dialog.SelectedPath, "license.txt");
|
||||||
|
File.WriteAllText(path, LicenseTextBox.Text);
|
||||||
|
MessageBox.Show($"激活码已保存到:{path}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class HardwareInfo
|
||||||
|
{
|
||||||
|
public static string GetMachineCode()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string cpu = GetWmiInfo("Win32_Processor", "ProcessorId");
|
||||||
|
string board = GetWmiInfo("Win32_BaseBoard", "SerialNumber");
|
||||||
|
string disk = GetWmiInfo("Win32_PhysicalMedia", "SerialNumber"); // 物理硬盘序列号
|
||||||
|
|
||||||
|
// 拼接并哈希,只取前16位,方便复制
|
||||||
|
string raw = $"{cpu}@{board}@{disk}";
|
||||||
|
using (var sha = SHA256.Create())
|
||||||
|
{
|
||||||
|
byte[] bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(raw));
|
||||||
|
return BitConverter.ToString(bytes).Replace("-", "").Substring(0, 16).ToUpper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return "ERROR-HARDWARE-ID";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetWmiInfo(string table, string prop)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var mc = new ManagementClass(table))
|
||||||
|
foreach (var mo in mc.GetInstances())
|
||||||
|
{
|
||||||
|
string val = mo[prop]?.ToString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(val)) return val.Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using System.Windows.Shapes;
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
namespace KeyGen
|
namespace KeyGen
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class ColorPanel : Control
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ICommand SelectPresetColorCommand { get; }
|
public ICommand SelectPresetColorCommand { get; }
|
||||||
|
|
||||||
private void ExecuteSelectPresetColor(object parameter)
|
private void ExecuteSelectPresetColor(object? parameter)
|
||||||
{
|
{
|
||||||
if (parameter is Color color)
|
if (parameter is Color color)
|
||||||
{
|
{
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
|||||||
<ResourceDictionary
|
<ResourceDictionary
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:assists="clr-namespace:Melskin.Assists"
|
xmlns:assists="clr-namespace:Melskin.Assists"
|
||||||
xmlns:controls="clr-namespace:Melskin.Controls"
|
xmlns:controls="clr-namespace:Melskin.Controls">
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
|
||||||
|
|
||||||
<Style TargetType="{x:Type controls:Hyperlink}">
|
<Style TargetType="{x:Type controls:Hyperlink}">
|
||||||
<Setter Property="Background" Value="{x:Null}" />
|
<Setter Property="Background" Value="{x:Null}" />
|
||||||
@@ -12,8 +12,6 @@
|
|||||||
<Setter Property="VerticalAlignment" Value="Center" />
|
<Setter Property="VerticalAlignment" Value="Center" />
|
||||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||||
<Setter Property="Foreground" Value="{DynamicResource TextLinkBrush}" />
|
<Setter Property="Foreground" Value="{DynamicResource TextLinkBrush}" />
|
||||||
<Setter Property="assists:ColorAssist.MouseOverForeground" Value="{DynamicResource PrimaryHoverBrush}" />
|
|
||||||
<Setter Property="assists:ColorAssist.FocusedForeground" Value="{DynamicResource PrimaryFocusedBrush}" />
|
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="{x:Type controls:Hyperlink}">
|
<ControlTemplate TargetType="{x:Type controls:Hyperlink}">
|
||||||
@@ -23,29 +21,27 @@
|
|||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<controls:IconElement
|
<controls:IconElement
|
||||||
Foreground="{DynamicResource TextLinkBrush}"
|
x:Name="Icon"
|
||||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||||
Symbol="Link"
|
|
||||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||||
x:Name="Icon" />
|
Foreground="{TemplateBinding Foreground}"
|
||||||
|
Symbol="Link" />
|
||||||
<ContentPresenter
|
<ContentPresenter
|
||||||
|
x:Name="Content"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||||
x:Name="Content" />
|
TextBlock.Foreground="{TemplateBinding Foreground}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<ControlTemplate.Triggers>
|
<ControlTemplate.Triggers>
|
||||||
<Trigger Property="IsMouseOver" Value="True">
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
<Setter Property="Foreground" TargetName="Icon" Value="{Binding Path=(assists:ColorAssist.MouseOverForeground), Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryHoverBrush}" />
|
||||||
<Setter Property="TextElement.Foreground" TargetName="Content" Value="{Binding Path=(assists:ColorAssist.MouseOverForeground), Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
|
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Trigger Property="IsPressed" Value="True">
|
<Trigger Property="IsPressed" Value="True">
|
||||||
<Setter Property="Foreground" TargetName="Icon" Value="{Binding Path=(assists:ColorAssist.FocusedForeground), Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryPressedBrush}" />
|
||||||
<Setter Property="TextElement.Foreground" TargetName="Content" Value="{Binding Path=(assists:ColorAssist.FocusedForeground), Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
|
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Trigger Property="IsVisited" Value="True">
|
<Trigger Property="IsVisited" Value="True">
|
||||||
<Setter Property="Foreground" TargetName="Icon" Value="{Binding Path=(assists:ColorAssist.FocusedForeground), Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
|
<Setter Property="Foreground" Value="RoyalBlue" />
|
||||||
<Setter Property="TextElement.Foreground" TargetName="Content" Value="{Binding Path=(assists:ColorAssist.FocusedForeground), Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
|
|
||||||
</Trigger>
|
</Trigger>
|
||||||
</ControlTemplate.Triggers>
|
</ControlTemplate.Triggers>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
@@ -9,7 +9,6 @@ namespace Melskin.Controls;
|
|||||||
public class Hyperlink : ButtonBase
|
public class Hyperlink : ButtonBase
|
||||||
{
|
{
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 已经浏览过的依赖属性。
|
/// 已经浏览过的依赖属性。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -22,13 +21,11 @@ public class Hyperlink : ButtonBase
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 定义私有的 Key:这是“写入权限”的钥匙,只有在这个类内部才能拿到
|
/// 定义私有的 Key:这是“写入权限”的钥匙,只有在这个类内部才能拿到
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly DependencyProperty IsVisitedProperty =
|
public static readonly DependencyProperty IsVisitedProperty;
|
||||||
IsVisitedPropertyKey.DependencyProperty;
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 表示已经浏览过的依赖属性。
|
/// 表示已经浏览过的依赖属性。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly DependencyPropertyKey IsVisitedPropertyKey =
|
public static readonly DependencyPropertyKey IsVisitedPropertyKey;
|
||||||
DependencyProperty.RegisterReadOnly(nameof(IsVisited), typeof(bool), typeof(Hyperlink), new PropertyMetadata(false));
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 外部调用此方法来将超链接标记为已访问。
|
/// 外部调用此方法来将超链接标记为已访问。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -53,7 +50,11 @@ public class Hyperlink : ButtonBase
|
|||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
static Hyperlink()
|
static Hyperlink()
|
||||||
{ DefaultStyleKeyProperty.OverrideMetadata(typeof(Hyperlink), new FrameworkPropertyMetadata(typeof(Hyperlink))); }
|
{
|
||||||
|
IsVisitedPropertyKey = DependencyProperty.RegisterReadOnly(nameof(IsVisited), typeof(bool), typeof(Hyperlink), new PropertyMetadata(false));
|
||||||
|
IsVisitedProperty = IsVisitedPropertyKey.DependencyProperty;
|
||||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(Hyperlink), new FrameworkPropertyMetadata(typeof(Hyperlink)));
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 点击后的事件
|
/// 点击后的事件
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user