Files
MRCC/launcher/PCL-CE/Plain Craft Launcher 2/Pages/PageInstance/MyLocalModItem.xaml.cs
T

887 lines
32 KiB
C#
Raw Normal View History

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.VisualBasic;
using PCL.Core.App;
using PCL.Core.Utils;
using PCL.Core.Utils.Exts;
using PCL.Core.App.Localization;
namespace PCL;
public partial class MyLocalCompItem
{
private string GetUpdateCompareDescription()
{
var currentName = Entry.compFile.FileName.Replace(".jar", "");
var newestName = Entry.UpdateFile.FileName.Replace(".jar", "");
// 简化名称对比
var currentSegs = currentName.Split('-').ToList();
var newestSegs = newestName.Split('-').ToList();
var shortened = false;
foreach (var Seg in currentSegs.ToList())
{
if (!newestSegs.Contains(Seg))
continue;
currentSegs.Remove(Seg);
newestSegs.Remove(Seg);
shortened = true;
}
if (shortened && currentSegs.Any() && newestSegs.Any())
{
currentName = currentSegs.Join("-");
newestName = newestSegs.Join("-");
Entry._Version = currentName; // 使用网络信息作为显示的版本号
}
return
Lang.Text("Instance.Resource.Item.UpdateCompare", currentName, Lang.TimeSpan(Entry.compFile.ReleaseDate - DateTime.Now), newestName, Lang.TimeSpan(Entry.UpdateFile.ReleaseDate - DateTime.Now));
}
public void Refresh()
{
Dispatcher.BeginInvoke(new Func<Task>(async () =>
{
// 更新
if (Entry.CanUpdate)
{
BtnUpdate.Visibility = Visibility.Visible;
BtnUpdate.ToolTip = $"{GetUpdateCompareDescription()}\r\n{Lang.Text("Instance.Resource.Item.UpdateToolTip")}";
}
else
{
BtnUpdate.Visibility = Visibility.Collapsed;
}
// 标题与描述
string descFileName;
if (Entry.IsFolder)
// 文件夹项的特殊处理
descFileName = Entry.Name;
else
switch (Entry.State)
{
case ModLocalComp.LocalCompFile.LocalFileStatus.Fine:
{
descFileName = ModBase.GetFileNameWithoutExtentionFromPath(Entry.path);
break;
}
case ModLocalComp.LocalCompFile.LocalFileStatus.Disabled:
{
descFileName =
ModBase.GetFileNameWithoutExtentionFromPath(Entry.path.Replace(".disabled", "")
.Replace(".old", "")); // McMod.McModState.Unavailable
break;
}
default:
{
descFileName = ModBase.GetFileNameFromPath(Entry.path);
break;
}
}
string newDescription;
var compTemp = Entry.Comp;
if (Entry.IsFolder)
{
// 文件夹项的特殊显示
Title = Entry.Name;
newDescription = Entry.Description;
}
else if (Config.Download.Comp.UiCompNameSolution == 1)
{
// 标题显示文件名,详情显示译名
// 标题
Title = descFileName;
SubTitle = "";
// 描述
if (Entry.Comp is null)
{
newDescription = Entry.Name;
}
else
{
var titles = await Task.Run(() => compTemp.GetControlTitle(false));
newDescription = titles.Key + titles.Value;
}
newDescription = newDescription.Replace(" | ", " / ");
if (Entry.Version is not null)
newDescription += $" ({Entry.Version})";
}
else
{
// 标题显示译名,详情显示文件名
// 标题
if (Entry.Comp is null)
{
Title = Entry.Name;
SubTitle = Entry.Version is null ? "" : " | " + Entry.Version;
}
else
{
var titles = await Task.Run(() => compTemp.GetControlTitle(false));
Title = titles.Key;
SubTitle = titles.Value + (Entry.Version is null ? "" : " | " + Entry.Version);
}
// 描述
newDescription = descFileName;
}
if (Entry.Comp is not null)
newDescription += ": " + Entry.Comp.Description.Replace("\r", "").Replace("\n", "");
else if (Entry.Description is not null)
newDescription += ": " + Entry.Description.Replace("\r", "").Replace("\n", "");
else if (!Entry.IsFileAvailable) newDescription += ": " + Lang.Text("Instance.Resource.Item.InfoUnavailable");
Description = newDescription;
if (Checked)
LabTitle.SetResourceReference(TextBlock.ForegroundProperty,
Entry.State == ModLocalComp.LocalCompFile.LocalFileStatus.Fine ? "ColorBrush2" : "ColorBrush5");
else
LabTitle.SetResourceReference(TextBlock.ForegroundProperty,
Entry.State == ModLocalComp.LocalCompFile.LocalFileStatus.Fine ? "ColorBrush1" : "ColorBrushGray4");
// 主 Logo
Logo = Entry.GetLogo();
// 图标右下角的 Logo
if (Entry.State == ModLocalComp.LocalCompFile.LocalFileStatus.Fine)
{
if (imgState is not null)
{
Children.Remove(imgState);
imgState = null;
}
}
else
{
if (imgState is null)
{
imgState = new Image
{
Width = 20d,
Height = 20d,
Margin = new Thickness(0d, 0d, -5, -3),
IsHitTestVisible = false,
HorizontalAlignment = HorizontalAlignment.Right,
VerticalAlignment = VerticalAlignment.Bottom
};
RenderOptions.SetBitmapScalingMode(imgState, BitmapScalingMode.HighQuality);
SetColumn(imgState, 1);
SetRow(imgState, 1);
SetRowSpan(imgState, 2);
Children.Add(imgState);
// <Image x:Name="ImgState" RenderOptions.BitmapScalingMode="HighQuality" Width="16" Height="16" Margin="0,0,-3,-1"
// Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" IsHitTestVisible="False"
// HorizontalAlignment="Right" VerticalAlignment="Bottom"
// Source="/Images/Icons/Unavailable.png" />
}
imgState.Source = new MyBitmap(ModBase.pathImage + $"Icons/{Entry.State}.png");
}
// 标签
if (Entry.IsFolder)
// 为文件夹添加标签
Tags = new List<string> { Lang.Text("Instance.Resource.Item.FolderTag") };
else if (Entry.Comp is not null) Tags = Entry.Comp.Tags;
}));
}
public void RefreshColor(object sender, EventArgs e)
{
InitLate(sender, e);
// 触发颜色动画
var time = IsMouseOver ? 120 : 180;
var ani = new List<ModAnimation.AniData>();
// ButtonStack
if (buttonStack is not null)
{
if (IsMouseOver)
{
ani.Add(ModAnimation.AaOpacity(buttonStack, 1d - buttonStack.Opacity, (int)Math.Round(time * 0.7d),
(int)Math.Round(time * 0.3d)));
ani.Add(ModAnimation.AaDouble(
i => ColumnPaddingRight.Width =
new GridLength(Math.Max(0, ColumnPaddingRight.Width.Value + (double)i)),
5 + Buttons.Count() * 25 - ColumnPaddingRight.Width.Value, (int)Math.Round(time * 0.3d),
(int)Math.Round(time * 0.7d)));
}
else
{
ani.Add(ModAnimation.AaOpacity(buttonStack, -buttonStack.Opacity, (int)Math.Round(time * 0.4d)));
ani.Add(ModAnimation.AaDouble(
i => ColumnPaddingRight.Width =
new GridLength(Math.Max(0, ColumnPaddingRight.Width.Value + (double)i)),
4d - ColumnPaddingRight.Width.Value, (int)Math.Round(time * 0.4d)));
}
}
// RectBack
if (IsMouseOver || Checked)
{
ani.AddRange(new[]
{
ModAnimation.AaColor(RectBack, Border.BackgroundProperty, isMouseDown ? "ColorBrush6" : "ColorBrushBg1",
time),
ModAnimation.AaOpacity(RectBack, 1d - RectBack.Opacity, time, ease: new ModAnimation.AniEaseOutFluent())
});
if (isMouseDown)
ani.Add(ModAnimation.AaScaleTransform(RectBack,
0.996d - ((ScaleTransform)RectBack.RenderTransform).ScaleX, (int)Math.Round(time * 1.2d),
ease: new ModAnimation.AniEaseOutFluent()));
else
ani.Add(ModAnimation.AaScaleTransform(RectBack, 1d - ((ScaleTransform)RectBack.RenderTransform).ScaleX,
(int)Math.Round(time * 1.2d), ease: new ModAnimation.AniEaseOutFluent()));
}
else
{
ani.AddRange(new[]
{
ModAnimation.AaOpacity(RectBack, -RectBack.Opacity, time),
ModAnimation.AaScaleTransform(RectBack, 0.996d - ((ScaleTransform)RectBack.RenderTransform).ScaleX,
time, ease: new ModAnimation.AniEaseOutFluent()),
ModAnimation.AaScaleTransform(RectBack, -0.196d, 1, after: true)
});
}
ModAnimation.AniStart(ani, "LocalModItem Color " + Uuid);
}
// 触发虚拟化内容
private void InitLate(object sender, EventArgs e)
{
if (buttonHandler is not null)
{
buttonHandler((MyLocalCompItem)sender, e);
buttonHandler = null;
}
}
// 显示更新日志
private void BtnUpdate_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
ShowUpdateLog();
}
private void ShowUpdateLog()
{
if (Entry.Comp is not null)
{
if (!Information.IsNumeric(Entry.Comp.Id))
{
var modrinthUrl = Entry.changelogUrls.FirstOrDefault(x => x.Contains("modrinth.com"));
if (modrinthUrl is not null)
{
ModBase.OpenWebsite(modrinthUrl);
return;
}
}
else
{
var curseForgeUrl = Entry.changelogUrls.FirstOrDefault(x => x.Contains("curseforge.com"));
if (curseForgeUrl is not null)
{
ModBase.OpenWebsite(curseForgeUrl);
return;
}
}
}
ModBase.Log(
Lang.Text("Instance.Resource.Item.OpenChangelogFailed"),
ModBase.LogLevel.Hint,
userSummary: Lang.Text("Instance.Resource.Item.OpenChangelogFailed"));
}
// 触发更新
private void BtnUpdate_Click(object sender, EventArgs e)
{
switch (ModMain.MyMsgBox(
$"{Lang.Text("Instance.Resource.Item.UpdateConfirm.Message", Entry.Name)}\r\n\r\n{GetUpdateCompareDescription()}",
Lang.Text("Instance.Resource.Item.UpdateConfirm.Title"),
Lang.Text("Instance.Resource.Item.Update"), Lang.Text("Instance.Resource.Item.ViewChangelog"), Lang.Text("Common.Action.Cancel")))
{
case 1: // 更新
{
switch (Entry.Comp.Type)
{
case ModComp.CompType.Mod:
{
ModMain.frmInstanceMod ??= new PageInstanceCompResource(ModComp.CompType.Mod);
ModMain.frmInstanceMod.UpdateResource(new[] { Entry });
break;
}
case ModComp.CompType.ResourcePack:
{
ModMain.frmInstanceResourcePack ??= new PageInstanceCompResource(ModComp.CompType.ResourcePack);
ModMain.frmInstanceResourcePack.UpdateResource(new[] { Entry });
break;
}
case ModComp.CompType.Shader:
{
ModMain.frmInstanceShader ??= new PageInstanceCompResource(ModComp.CompType.Shader);
ModMain.frmInstanceShader.UpdateResource(new[] { Entry });
break;
}
case ModComp.CompType.DataPack:
{
ModMain.frmInstanceSavesDatapack ??= new PageInstanceSavesDatapack();
ModMain.frmInstanceSavesDatapack.UpdateResource(new[] { Entry });
break;
}
}
break;
}
case 2: // 查看更新日志
{
ShowUpdateLog();
break;
}
case 3: // 取消
{
break;
}
}
}
// 自适应(#4465
private void PanTitle_SizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs)
{
// 0:全部舒展:Auto - Auto - (Auto) - 1*
// 1:压缩 SubtitleAuto - 1* - (Auto) - 0
// 2:继续压缩 Title1* - 0 - (Auto) - 0
var currentCompressLevel =
ColumnExtend.Width.IsStar ? 0 : ColumnTitle.Width.IsStar ? 2 : 1; // Subtitle 可能是 Collapsed
var newCompressLevel = default(int);
switch (currentCompressLevel)
{
case 0:
{
if (ColumnExtend.ActualWidth < 0.5d)
newCompressLevel = LabSubtitle.Visibility == Visibility.Collapsed ? 2 : 1;
else
return;
break;
}
case 1:
{
if (ColumnSubtitle.ActualWidth < 0.5d)
newCompressLevel = 2;
else if (!LabSubtitle.IsTextTrimmed())
newCompressLevel = 0;
else
return;
break;
}
case 2:
{
if (!LabTitle.IsTextTrimmed())
newCompressLevel = LabSubtitle.Visibility == Visibility.Collapsed ? 0 : 1;
else
return;
break;
}
}
switch (newCompressLevel)
{
case 0:
{
// 全部舒展:Auto - Auto - (Auto) - 1*
ColumnTitle.Width = GridLength.Auto;
ColumnSubtitle.Width = GridLength.Auto;
ColumnExtend.Width = new GridLength(1d, GridUnitType.Star);
break;
}
case 1:
{
// 压缩 SubtitleAuto - 1* - (Auto) - 0
ColumnTitle.Width = GridLength.Auto;
ColumnSubtitle.Width = new GridLength(1d, GridUnitType.Star);
ColumnExtend.Width = new GridLength(0d, GridUnitType.Pixel);
break;
}
case 2:
{
// 继续压缩 Title1* - 0 - (Auto) - 0
ColumnTitle.Width = new GridLength(1d, GridUnitType.Star);
ColumnSubtitle.Width = new GridLength(0d, GridUnitType.Pixel);
ColumnExtend.Width = new GridLength(0d, GridUnitType.Pixel);
break;
}
}
}
#region 基础属性
public int Uuid = ModBase.GetUuid();
// Logo
public string Logo
{
get => PathLogo.Source;
set => PathLogo.Source = value;
}
// 标题
public string Title
{
get => field;
set
{
var rawValue = value;
switch (Entry.State)
{
case ModLocalComp.LocalCompFile.LocalFileStatus.Fine:
{
LabTitle.TextDecorations = null;
break;
}
case ModLocalComp.LocalCompFile.LocalFileStatus.Disabled:
{
LabTitle.TextDecorations = TextDecorations.Strikethrough;
break;
}
case ModLocalComp.LocalCompFile.LocalFileStatus.Unavailable:
{
LabTitle.TextDecorations = TextDecorations.Strikethrough;
value += Lang.Text("Instance.Resource.Item.ErrorSuffix");
break;
}
}
if ((LabTitle.Text ?? "") == (value ?? ""))
return;
LabTitle.Text = value;
field = rawValue;
}
}
// 副标题
public string SubTitle
{
get => LabSubtitle?.Text ?? "";
set
{
if ((LabSubtitle.Text ?? "") == (value ?? ""))
return;
LabSubtitle.Text = value;
LabSubtitle.Visibility = string.IsNullOrEmpty(value) ? Visibility.Collapsed : Visibility.Visible;
}
}
// 描述
public string Description
{
get => LabInfo.Text;
set
{
if ((LabInfo.Text ?? "") == (value ?? ""))
return;
LabInfo.Text = value;
}
}
// Tag
public List<string> Tags
{
set
{
PanTags.Children.Clear();
PanTags.Visibility = value.Any() ? Visibility.Visible : Visibility.Collapsed;
foreach (var TagText in value)
{
var newTag = new Border
{
Background = new SolidColorBrush(Color.FromArgb(12, 0, 0, 0)),
Padding = new Thickness(3d, 1d, 3d, 1d),
CornerRadius = new CornerRadius(3d),
Margin = new Thickness(0d, 0d, 3d, 0d),
SnapsToDevicePixels = true,
UseLayoutRounding = false
};
var tagTextBlock = new TextBlock
{
Text = TagText,
Foreground = new SolidColorBrush(ThemeManager.IsDarkMode
? Color.FromArgb(88, 255, 255, 255)
: Color.FromArgb(88, 136, 136, 136)),
FontSize = 11d
};
newTag.Child = tagTextBlock;
PanTags.Children.Add(newTag);
}
}
}
// 相关联的 Mod
public ModLocalComp.LocalCompFile Entry
{
get => (ModLocalComp.LocalCompFile)Tag;
set => Tag = value;
}
#endregion
#region 点击与勾选
// 触发点击事件
public event ClickEventHandler? Click;
public delegate void ClickEventHandler(object sender, MouseButtonEventArgs e);
public MyLocalCompItem()
{
InitializeComponent();
PreviewMouseLeftButtonUp += Button_MouseUp;
PreviewMouseLeftButtonDown += Button_MouseDown;
MouseLeave += Button_MouseLeave;
PreviewMouseLeftButtonUp += Button_MouseLeave;
MouseLeftButtonDown += Button_MouseSwipeStart;
MouseEnter += Button_MouseSwipe;
MouseLeave += Button_MouseSwipe;
MouseLeftButtonUp += Button_MouseSwipe;
Loaded += (_, _) => Refresh();
MouseEnter += RefreshColor;
MouseLeave += RefreshColor;
MouseLeftButtonDown += RefreshColor;
MouseLeftButtonUp += RefreshColor;
Changed += RefreshColor;
// Handles
BtnUpdate.PreviewMouseRightButtonUp += BtnUpdate_PreviewMouseRightButtonUp;
BtnUpdate.Click += BtnUpdate_Click;
PanTitle.SizeChanged += PanTitle_SizeChanged;
}
private void Button_MouseUp(object sender, MouseButtonEventArgs e)
{
if (isMouseDown)
{
Click?.Invoke(sender, e);
if (e.Handled)
return;
ModBase.Log("[Control] 按下本地 Mod 列表项:" + LabTitle.Text);
}
}
// 鼠标点击判定
private bool isMouseDown;
private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
if (!IsMouseDirectlyOver)
return;
isMouseDown = true;
if (buttonStack is not null)
buttonStack.IsHitTestVisible = false;
}
private void Button_MouseLeave(object sender, object e)
{
isMouseDown = false;
if (buttonStack is not null)
buttonStack.IsHitTestVisible = true;
}
// 滑动选中
public class SwipeSelect
{
public int Start { get; set; }
public int End { get; set; }
public bool Swiping
{
get => field;
set
{
field = value;
if (TargetFrm is not null)
try
{
var cardSelect = Interaction.CallByName(TargetFrm, "CardSelect", CallType.Get);
Interaction.CallByName(cardSelect, "IsHitTestVisible", CallType.Set, !value);
}
catch
{
}
}
}
public bool SwipeToState { get; set; }
public object TargetFrm { get; set; }
}
public SwipeSelect CurrentSwipe { get; set; }
private void Button_MouseSwipeStart(object sender, object e)
{
if (Parent is null)
return; // Mod 可能已被删除(#3824
// 开始滑动
var index = ((StackPanel)Parent).Children.IndexOf(this);
CurrentSwipe.Start = index;
CurrentSwipe.End = index;
CurrentSwipe.Swiping = true;
CurrentSwipe.SwipeToState = !Checked;
}
private void Button_MouseSwipe(object sender, object e)
{
if (Parent is null)
return; // Mod 可能已被删除(#3824
// 结束滑动
if (Mouse.LeftButton != MouseButtonState.Pressed || !(Mouse.DirectlyOver is MyLocalCompItem)) // #5771
{
CurrentSwipe.Swiping = false;
return;
}
// 计算滑动范围
var elements = ((StackPanel)Parent).Children;
var index = elements.IndexOf(this);
CurrentSwipe.Start =
(int)Math.Round(ModBase.MathClamp(Math.Min(CurrentSwipe.Start, index), 0d, elements.Count - 1));
CurrentSwipe.End =
(int)Math.Round(ModBase.MathClamp(Math.Max(CurrentSwipe.End, index), 0d, elements.Count - 1));
// 勾选所有范围中的项
if (CurrentSwipe.Start == CurrentSwipe.End)
return;
for (int i = CurrentSwipe.Start, loopTo = CurrentSwipe.End; i <= loopTo; i++)
{
var item = (MyLocalCompItem)elements[i];
item.InitLate(item, (EventArgs)e);
item.Checked = CurrentSwipe.SwipeToState;
}
}
// 勾选状态
public event CheckEventHandler? Check;
public delegate void CheckEventHandler(object sender, ModBase.RouteEventArgs e);
public event ChangedEventHandler? Changed;
public delegate void ChangedEventHandler(object sender, ModBase.RouteEventArgs e);
public bool Checked
{
get => field;
set
{
try
{
// 触发属性值修改
var rawValue = field;
if (value == field)
return;
field = value;
var ChangedEventArgs = new ModBase.RouteEventArgs();
if (IsInitialized)
{
Changed?.Invoke(this, ChangedEventArgs);
if (ChangedEventArgs.handled)
{
field = rawValue;
return;
}
}
if (value)
{
var checkEventArgs = new ModBase.RouteEventArgs();
Check?.Invoke(this, checkEventArgs);
if (checkEventArgs.handled)
return;
}
// 更改动画
if (this.IsVisibleInWindow(ModMain.frmMain))
{
var anim = new List<ModAnimation.AniData>();
if (Checked)
{
// 由无变有
var delta = 32d - RectCheck.ActualHeight;
anim.Add(ModAnimation.AaHeight(RectCheck, delta * 0.4d, 200,
ease: new ModAnimation.AniEaseOutFluent(ModAnimation.AniEasePower.Weak)));
anim.Add(ModAnimation.AaHeight(RectCheck, delta * 0.6d, 300,
ease: new ModAnimation.AniEaseOutBack(ModAnimation.AniEasePower.Weak)));
anim.Add(ModAnimation.AaOpacity(RectCheck, 1d - RectCheck.Opacity, 30));
RectCheck.VerticalAlignment = VerticalAlignment.Center;
RectCheck.Margin = new Thickness(-3, 0d, 0d, 0d);
anim.Add(ModAnimation.AaColor(LabTitle, TextBlock.ForegroundProperty,
Entry.State == ModLocalComp.LocalCompFile.LocalFileStatus.Fine
? "ColorBrush2"
: "ColorBrush5", 200));
}
else
{
// 由有变无
anim.Add(ModAnimation.AaHeight(RectCheck, -RectCheck.ActualHeight, 120,
ease: new ModAnimation.AniEaseInFluent(ModAnimation.AniEasePower.Weak)));
anim.Add(ModAnimation.AaOpacity(RectCheck, -RectCheck.Opacity, 70, 40));
RectCheck.VerticalAlignment = VerticalAlignment.Center;
anim.Add(ModAnimation.AaColor(LabTitle, TextBlock.ForegroundProperty,
LabTitle.TextDecorations is null ? "ColorBrush1" : "ColorBrushGray4", 120));
}
ModAnimation.AniStart(anim, "MyLocalCompItem Checked " + Uuid);
}
else
{
// 不在窗口上时直接设置
RectCheck.VerticalAlignment = VerticalAlignment.Center;
RectCheck.Margin = new Thickness(-3, 0d, 0d, 0d);
if (Checked)
{
RectCheck.Height = 32d;
RectCheck.Opacity = 1d;
LabTitle.SetResourceReference(TextBlock.ForegroundProperty,
Entry.State == ModLocalComp.LocalCompFile.LocalFileStatus.Fine
? "ColorBrush2"
: "ColorBrush5");
}
else
{
RectCheck.Height = 0d;
RectCheck.Opacity = 0d;
LabTitle.SetResourceReference(TextBlock.ForegroundProperty,
Entry.State == ModLocalComp.LocalCompFile.LocalFileStatus.Fine
? "ColorBrush1"
: "ColorBrushGray4");
}
ModAnimation.AniStop("MyLocalCompItem Checked " + Uuid);
}
}
catch (Exception ex)
{
ModBase.Log(ex, "设置 Checked 失败");
}
}
}
#endregion
#region 后加载内容
// 右下角状态指示图标
private Image imgState;
// 指向背景
public Border RectBack
{
get
{
if (field is null)
{
var rect = new Border
{
Name = "RectBack",
CornerRadius = new CornerRadius(3d),
RenderTransform = new ScaleTransform(0.8d, 0.8d),
RenderTransformOrigin = new Point(0.5d, 0.5d),
BorderThickness = new Thickness(ModBase.GetWPFSize(1d)),
SnapsToDevicePixels = true,
IsHitTestVisible = false,
Opacity = 0d
};
rect.SetResourceReference(Border.BackgroundProperty, "ColorBrush7");
rect.SetResourceReference(Border.BorderBrushProperty, "ColorBrush6");
SetColumnSpan(rect, 999);
SetRowSpan(rect, 999);
Children.Insert(0, rect);
field = rect;
// <!--<corelocal:BlurBorder x:Name = "RectBack" CornerRadius="3" RenderTransformOrigin="0.5,0.5" SnapsToDevicePixels="True"
// IsHitTestVisible = "False" Opacity="0" BorderThickness="1"
// Grid.ColumnSpan = "4" Background="{DynamicResource ColorBrush7}" BorderBrush="{DynamicResource ColorBrush6}"/>-->
}
return field;
}
}
// 按钮
public Action<MyLocalCompItem, EventArgs> buttonHandler;
public FrameworkElement buttonStack;
public IEnumerable<MyIconButton> Buttons
{
get => field;
set
{
field = value;
// 移除原 Stack
if (buttonStack is not null)
{
Children.Remove(buttonStack);
buttonStack = null;
}
if (!value.Any())
return;
// 添加新 Stack
buttonStack = new StackPanel
{
Opacity = 0d,
Margin = new Thickness(0d, 0d, 5d, 0d),
SnapsToDevicePixels = false,
Orientation = (Orientation)System.Windows.Forms.Orientation.Horizontal,
HorizontalAlignment = HorizontalAlignment.Right,
VerticalAlignment = VerticalAlignment.Center,
UseLayoutRounding = false
};
SetColumnSpan(buttonStack, 10);
SetRowSpan(buttonStack, 10);
// 构造按钮
foreach (var Btn in value)
{
if (Btn.Height.Equals(double.NaN))
Btn.Height = 25d;
if (Btn.Width.Equals(double.NaN))
Btn.Width = 25d;
((StackPanel)buttonStack).Children.Add(Btn);
}
Children.Add(buttonStack);
}
}
// 勾选条
public Border RectCheck
{
get
{
if (field is null)
{
field = new Border
{
Width = 5d,
Height = Checked ? double.NaN : 0d,
CornerRadius = new CornerRadius(2d, 2d, 2d, 2d),
VerticalAlignment = Checked ? VerticalAlignment.Stretch : VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Left,
UseLayoutRounding = false,
SnapsToDevicePixels = false,
Margin = Checked ? new Thickness(-3, 6d, 0d, 6d) : new Thickness(-3, 0d, 0d, 0d)
};
field.SetResourceReference(Border.BackgroundProperty, "ColorBrush3");
SetRowSpan(field, 10);
Children.Add(field);
}
return field;
}
}
#endregion
}