mirror of
https://github.com/LorisYounger/VPet.git
synced 2024-08-30 18:42:36 +00:00
VPet.Solution
实装反射工具
This commit is contained in:
parent
2993c5d5eb
commit
6aff72bf91
@ -1,10 +1,12 @@
|
|||||||
using System.ComponentModel;
|
using HKW.HKWUtils.Observable;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
namespace VPet.Solution.Models.SettingEditor;
|
namespace VPet.Solution.Models.SettingEditor;
|
||||||
|
|
||||||
public class GraphicsSettingModel : ObservableClass<GraphicsSettingModel>
|
public class GraphicsSettingModel : ObservableClass<GraphicsSettingModel>
|
||||||
{
|
{
|
||||||
|
#region
|
||||||
private double _zoomLevel = 1;
|
private double _zoomLevel = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -17,6 +19,24 @@ public class GraphicsSettingModel : ObservableClass<GraphicsSettingModel>
|
|||||||
set => SetProperty(ref _zoomLevel, value);
|
set => SetProperty(ref _zoomLevel, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double _zoomLevelMinimum = 0.5;
|
||||||
|
|
||||||
|
[DefaultValue(0.5)]
|
||||||
|
public double ZoomLevelMinimum
|
||||||
|
{
|
||||||
|
get => _zoomLevelMinimum;
|
||||||
|
set => SetProperty(ref _zoomLevelMinimum, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double _zoomLevelMaximum = 3;
|
||||||
|
|
||||||
|
[DefaultValue(3)]
|
||||||
|
public double ZoomLevelMaximum
|
||||||
|
{
|
||||||
|
get => _zoomLevelMaximum;
|
||||||
|
set => SetProperty(ref _zoomLevelMaximum, value);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
private int _resolution = 1000;
|
private int _resolution = 1000;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -37,7 +57,14 @@ public class GraphicsSettingModel : ObservableClass<GraphicsSettingModel>
|
|||||||
public bool IsBiggerScreen
|
public bool IsBiggerScreen
|
||||||
{
|
{
|
||||||
get => _isBiggerScreen;
|
get => _isBiggerScreen;
|
||||||
set => SetProperty(ref _isBiggerScreen, value);
|
set
|
||||||
|
{
|
||||||
|
SetProperty(ref _isBiggerScreen, value);
|
||||||
|
if (value is true)
|
||||||
|
ZoomLevelMaximum = 8;
|
||||||
|
else
|
||||||
|
ZoomLevelMaximum = 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _topMost;
|
private bool _topMost;
|
||||||
@ -143,6 +170,7 @@ public class GraphicsSettingModel : ObservableClass<GraphicsSettingModel>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置中桌宠启动的位置
|
/// 设置中桌宠启动的位置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[ReflectionPropertyInfo(typeof(ObservablePointToPointConverter))]
|
||||||
public ObservablePoint StartRecordPoint
|
public ObservablePoint StartRecordPoint
|
||||||
{
|
{
|
||||||
get => _startRecordPoint;
|
get => _startRecordPoint;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using LinePutScript;
|
using LinePutScript;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using VPet.Solution.Properties;
|
using VPet.Solution.Properties;
|
||||||
@ -60,6 +61,8 @@ public class SettingModel : ObservableClass<SettingModel>
|
|||||||
|
|
||||||
private Setting _setting;
|
private Setting _setting;
|
||||||
|
|
||||||
|
private ReflectionOptions _saveReflectionOptions = new() { CheckValueEquals = true };
|
||||||
|
|
||||||
public SettingModel(Setting setting)
|
public SettingModel(Setting setting)
|
||||||
{
|
{
|
||||||
_setting = setting;
|
_setting = setting;
|
||||||
@ -68,21 +71,9 @@ public class SettingModel : ObservableClass<SettingModel>
|
|||||||
|
|
||||||
private GraphicsSettingModel LoadGraphicsSettings()
|
private GraphicsSettingModel LoadGraphicsSettings()
|
||||||
{
|
{
|
||||||
var graphicsSettings = new GraphicsSettingModel();
|
var graphicsSetting = new GraphicsSettingModel();
|
||||||
var sourceAccessor = ObjectAccessor.Create(_setting);
|
ReflectionUtils.SetValue(_setting, graphicsSetting);
|
||||||
var targetAccessor = ObjectAccessor.Create(graphicsSettings);
|
return graphicsSetting;
|
||||||
foreach (var property in typeof(GraphicsSettingModel).GetProperties())
|
|
||||||
{
|
|
||||||
if (sourceAccessor[property.Name] is Point point)
|
|
||||||
{
|
|
||||||
targetAccessor[property.Name] = new ObservablePoint(point);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
targetAccessor[property.Name] = sourceAccessor[property.Name];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return graphicsSettings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
@ -93,24 +84,6 @@ public class SettingModel : ObservableClass<SettingModel>
|
|||||||
|
|
||||||
private void SaveGraphicsSettings()
|
private void SaveGraphicsSettings()
|
||||||
{
|
{
|
||||||
var sourceAccessor = ObjectAccessor.Create(GraphicsSetting);
|
ReflectionUtils.SetValue(GraphicsSetting, _setting, _saveReflectionOptions);
|
||||||
var targetAccessor = ObjectAccessor.Create(_setting);
|
|
||||||
foreach (var property in typeof(GraphicsSettingModel).GetProperties())
|
|
||||||
{
|
|
||||||
//if (_settingProperties.Contains(property.Name) is false)
|
|
||||||
// continue;
|
|
||||||
var sourceValue = sourceAccessor[property.Name];
|
|
||||||
var targetValue = targetAccessor[property.Name];
|
|
||||||
if (sourceValue.Equals(targetValue))
|
|
||||||
continue;
|
|
||||||
if (sourceValue is ObservablePoint point)
|
|
||||||
{
|
|
||||||
targetAccessor[property.Name] = point.ToPoint();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
targetAccessor[property.Name] = sourceValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,6 @@ public class ObservablePoint : ObservableClass<ObservablePoint>, IEquatable<Obse
|
|||||||
Y = y;
|
Y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservablePoint(Point point)
|
|
||||||
{
|
|
||||||
X = point.X;
|
|
||||||
Y = point.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 复制一个新的对象
|
/// 复制一个新的对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -88,6 +82,19 @@ public class ObservablePoint : ObservableClass<ObservablePoint>, IEquatable<Obse
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ObservablePointToPointConverter : ReflectionConverterBase<ObservablePoint, Point>
|
||||||
|
{
|
||||||
|
public override Point Convert(ObservablePoint sourceValue)
|
||||||
|
{
|
||||||
|
return new(sourceValue.X, sourceValue.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ObservablePoint ConvertBack(Point targetValue)
|
||||||
|
{
|
||||||
|
return new(targetValue.X, targetValue.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///// <summary>
|
///// <summary>
|
||||||
///// 可观察地点
|
///// 可观察地点
|
||||||
///// </summary>
|
///// </summary>
|
||||||
|
180
VPet.Solution/Utils/ReflectionUtils.cs
Normal file
180
VPet.Solution/Utils/ReflectionUtils.cs
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
using FastMember;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace HKW.HKWUtils;
|
||||||
|
|
||||||
|
public static class ReflectionUtils
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 目标名称
|
||||||
|
/// <para>
|
||||||
|
/// (TargetType, (PropertyName, TargetPropertyName))
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
private static readonly Dictionary<Type, ReflectionObjectInfo> _typePropertyReflectionInfos =
|
||||||
|
new();
|
||||||
|
|
||||||
|
public static void SetValue<TSource, TTarget>(
|
||||||
|
TSource source,
|
||||||
|
TTarget target,
|
||||||
|
ReflectionOptions options = null!
|
||||||
|
)
|
||||||
|
{
|
||||||
|
options ??= new();
|
||||||
|
var sourceType = typeof(TSource);
|
||||||
|
var targetType = typeof(TTarget);
|
||||||
|
if (_typePropertyReflectionInfos.TryGetValue(sourceType, out var sourceInfo) is false)
|
||||||
|
sourceInfo = _typePropertyReflectionInfos[sourceType] = GetReflectionObjectInfo(
|
||||||
|
sourceType
|
||||||
|
);
|
||||||
|
if (_typePropertyReflectionInfos.TryGetValue(targetType, out var targetInfo) is false)
|
||||||
|
targetInfo = _typePropertyReflectionInfos[targetType] = GetReflectionObjectInfo(
|
||||||
|
targetType
|
||||||
|
);
|
||||||
|
|
||||||
|
var sourceAccessor = ObjectAccessor.Create(source);
|
||||||
|
var targetAccessor = ObjectAccessor.Create(target);
|
||||||
|
|
||||||
|
foreach (var property in sourceType.GetProperties())
|
||||||
|
{
|
||||||
|
// 获取源属性名
|
||||||
|
var sourcePropertyName = sourceInfo.PropertyInfos.TryGetValue(
|
||||||
|
property.Name,
|
||||||
|
out var sourceReflectionInfo
|
||||||
|
)
|
||||||
|
? sourceReflectionInfo.PropertyName
|
||||||
|
: property.Name;
|
||||||
|
if (targetInfo.PropertyNames.Contains(sourcePropertyName) is false)
|
||||||
|
continue;
|
||||||
|
// 获取目标属性名
|
||||||
|
var targetPropertyName = targetInfo.PropertyInfos.TryGetValue(
|
||||||
|
sourcePropertyName,
|
||||||
|
out var targetReflectionInfo
|
||||||
|
)
|
||||||
|
? targetReflectionInfo.PropertyName
|
||||||
|
: property.Name;
|
||||||
|
// 获取源值
|
||||||
|
var sourceValue = sourceAccessor[sourcePropertyName];
|
||||||
|
// 转换源值
|
||||||
|
if (sourceReflectionInfo?.Converter is IReflectionConverter sourceConverter)
|
||||||
|
sourceValue = sourceConverter.Convert(sourceValue);
|
||||||
|
else if (targetReflectionInfo?.Converter is IReflectionConverter targetConverter)
|
||||||
|
sourceValue = targetConverter.ConvertBack(sourceValue);
|
||||||
|
// 比较源值和目标值
|
||||||
|
if (options.CheckValueEquals)
|
||||||
|
{
|
||||||
|
var targetValue = targetAccessor[targetPropertyName];
|
||||||
|
if (sourceValue.Equals(targetValue))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
targetAccessor[targetPropertyName] = sourceValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReflectionObjectInfo GetReflectionObjectInfo(Type type)
|
||||||
|
{
|
||||||
|
var objectInfo = new ReflectionObjectInfo(type);
|
||||||
|
foreach (var property in type.GetProperties())
|
||||||
|
{
|
||||||
|
if (property.IsDefined(typeof(ReflectionPropertyInfoAttribute)))
|
||||||
|
{
|
||||||
|
var reflectionInfo = property.GetCustomAttribute<ReflectionPropertyInfoAttribute>();
|
||||||
|
if (string.IsNullOrWhiteSpace(reflectionInfo.PropertyName))
|
||||||
|
reflectionInfo.PropertyName = property.Name;
|
||||||
|
objectInfo.PropertyInfos[property.Name] = reflectionInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return objectInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反射对象信息
|
||||||
|
/// </summary>
|
||||||
|
public class ReflectionObjectInfo
|
||||||
|
{
|
||||||
|
public HashSet<string> PropertyNames { get; }
|
||||||
|
|
||||||
|
public Dictionary<string, ReflectionPropertyInfoAttribute> PropertyInfos { get; } = new();
|
||||||
|
|
||||||
|
public ReflectionObjectInfo(Type type)
|
||||||
|
{
|
||||||
|
PropertyNames = new(type.GetProperties().Select(p => p.Name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反射属性信息
|
||||||
|
/// </summary>
|
||||||
|
public class ReflectionPropertyInfoAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 目标属性名称
|
||||||
|
/// </summary>
|
||||||
|
public string PropertyName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反射转换器
|
||||||
|
/// </summary>
|
||||||
|
public IReflectionConverter? Converter { get; } = null;
|
||||||
|
|
||||||
|
public ReflectionPropertyInfoAttribute(Type converterType)
|
||||||
|
: this(string.Empty, converterType) { }
|
||||||
|
|
||||||
|
public ReflectionPropertyInfoAttribute(string name, Type? converterType = null)
|
||||||
|
{
|
||||||
|
PropertyName = name;
|
||||||
|
if (converterType is null)
|
||||||
|
return;
|
||||||
|
Converter = (IReflectionConverter)TypeAccessor.Create(converterType).CreateNew();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反射设置
|
||||||
|
/// </summary>
|
||||||
|
public class ReflectionOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 检查值是否相等, 若相等则跳过赋值
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(false)]
|
||||||
|
public bool CheckValueEquals { get; set; } = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反射转换器
|
||||||
|
/// </summary>
|
||||||
|
public interface IReflectionConverter
|
||||||
|
{
|
||||||
|
public object Convert(object sourceValue);
|
||||||
|
public object ConvertBack(object targetValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反射转换器
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TSource">源值类型</typeparam>
|
||||||
|
/// <typeparam name="TTarget">目标值类型</typeparam>
|
||||||
|
public abstract class ReflectionConverterBase<TSource, TTarget> : IReflectionConverter
|
||||||
|
{
|
||||||
|
public abstract TTarget Convert(TSource sourceValue);
|
||||||
|
|
||||||
|
public abstract TSource ConvertBack(TTarget targetValue);
|
||||||
|
|
||||||
|
object IReflectionConverter.Convert(object sourceValue)
|
||||||
|
{
|
||||||
|
return Convert((TSource)sourceValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
object IReflectionConverter.ConvertBack(object targetValue)
|
||||||
|
{
|
||||||
|
return ConvertBack((TTarget)targetValue);
|
||||||
|
}
|
||||||
|
}
|
@ -101,6 +101,7 @@
|
|||||||
<Compile Include="Utils\ClearFocus.cs" />
|
<Compile Include="Utils\ClearFocus.cs" />
|
||||||
<Compile Include="Utils\ElementHelper.cs" />
|
<Compile Include="Utils\ElementHelper.cs" />
|
||||||
<Compile Include="Utils\FindTopParent.cs" />
|
<Compile Include="Utils\FindTopParent.cs" />
|
||||||
|
<Compile Include="Utils\ReflectionUtils.cs" />
|
||||||
<Compile Include="ViewModels\MainWindowVM.cs" />
|
<Compile Include="ViewModels\MainWindowVM.cs" />
|
||||||
<Compile Include="ViewModels\SettingEditor\CustomizedSettingPageVM.cs" />
|
<Compile Include="ViewModels\SettingEditor\CustomizedSettingPageVM.cs" />
|
||||||
<Compile Include="ViewModels\SettingEditor\DiagnosticSettingPageVM.cs" />
|
<Compile Include="ViewModels\SettingEditor\DiagnosticSettingPageVM.cs" />
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using HKW.HKWUtils.Observable;
|
using HKW.HKWUtils.Observable;
|
||||||
using LinePutScript;
|
using LinePutScript;
|
||||||
|
using LinePutScript.Localization.WPF;
|
||||||
using Panuon.WPF.UI;
|
using Panuon.WPF.UI;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -47,7 +48,7 @@ public class SettingWindowVM : ObservableClass<SettingWindowVM>
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Command
|
#region Command
|
||||||
public ObservableCommand ResetSettingCommand { get; } = new();
|
public ObservableCommand<SettingModel> ResetSettingCommand { get; } = new();
|
||||||
public ObservableCommand<SettingModel> SaveSettingCommand { get; } = new();
|
public ObservableCommand<SettingModel> SaveSettingCommand { get; } = new();
|
||||||
public ObservableCommand SaveAllSettingCommand { get; } = new();
|
public ObservableCommand SaveAllSettingCommand { get; } = new();
|
||||||
#endregion
|
#endregion
|
||||||
@ -62,6 +63,13 @@ public class SettingWindowVM : ObservableClass<SettingWindowVM>
|
|||||||
PropertyChanged += MainWindowVM_PropertyChanged;
|
PropertyChanged += MainWindowVM_PropertyChanged;
|
||||||
ResetSettingCommand.ExecuteCommand += ResetSettingCommand_ExecuteCommand;
|
ResetSettingCommand.ExecuteCommand += ResetSettingCommand_ExecuteCommand;
|
||||||
SaveSettingCommand.ExecuteCommand += SaveSettingCommand_ExecuteCommand;
|
SaveSettingCommand.ExecuteCommand += SaveSettingCommand_ExecuteCommand;
|
||||||
|
SaveAllSettingCommand.ExecuteCommand += SaveAllSettingCommand_ExecuteCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveAllSettingCommand_ExecuteCommand()
|
||||||
|
{
|
||||||
|
foreach (var setting in _settings)
|
||||||
|
setting.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveSettingCommand_ExecuteCommand(SettingModel parameter)
|
private void SaveSettingCommand_ExecuteCommand(SettingModel parameter)
|
||||||
@ -69,22 +77,26 @@ public class SettingWindowVM : ObservableClass<SettingWindowVM>
|
|||||||
parameter.Save();
|
parameter.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResetSettingCommand_ExecuteCommand()
|
private void ResetSettingCommand_ExecuteCommand(SettingModel parameter)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
MessageBoxX.Show(
|
MessageBox.Show(
|
||||||
SettingWindow.Instance,
|
SettingWindow.Instance,
|
||||||
"确定重置吗",
|
"确定重置设置吗\n名称: {0}\n路径: {1}".Translate(parameter.Name, parameter.FilePath),
|
||||||
"",
|
"",
|
||||||
MessageBoxButton.YesNo,
|
MessageBoxButton.YesNo,
|
||||||
MessageBoxIcon.Warning
|
MessageBoxImage.Warning
|
||||||
)
|
)
|
||||||
is not MessageBoxResult.Yes
|
is not MessageBoxResult.Yes
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
CurrentSetting = _settings[_settings.IndexOf(CurrentSetting)] = new SettingModel(
|
CurrentSetting = _settings[_settings.IndexOf(CurrentSetting)] = new SettingModel(
|
||||||
new Setting("")
|
new Setting("")
|
||||||
);
|
)
|
||||||
|
{
|
||||||
|
Name = CurrentSetting.Name,
|
||||||
|
FilePath = CurrentSetting.FilePath
|
||||||
|
};
|
||||||
RefreshShowSettings(SearchSetting);
|
RefreshShowSettings(SearchSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,8 +107,8 @@
|
|||||||
x:Name="Slider_Zoom"
|
x:Name="Slider_Zoom"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
LargeChange="0.1"
|
LargeChange="0.1"
|
||||||
Maximum="3"
|
Maximum="{Binding GraphicsSetting.ZoomLevelMaximum}"
|
||||||
Minimum="0.5"
|
Minimum="{Binding GraphicsSetting.ZoomLevelMinimum}"
|
||||||
SmallChange="0.05"
|
SmallChange="0.05"
|
||||||
Style="{DynamicResource Slider_BaseStyle}"
|
Style="{DynamicResource Slider_BaseStyle}"
|
||||||
TickFrequency="0.05"
|
TickFrequency="0.05"
|
||||||
@ -117,8 +117,8 @@
|
|||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Foreground="{DynamicResource DARKPrimaryDarker}"
|
Foreground="{DynamicResource DARKPrimaryDarker}"
|
||||||
Interval="0.1"
|
Interval="0.1"
|
||||||
Maximum="3"
|
Maximum="{Binding GraphicsSetting.ZoomLevelMaximum}"
|
||||||
Minimum="0.5"
|
Minimum="{Binding GraphicsSetting.ZoomLevelMinimum}"
|
||||||
Style="{DynamicResource NumberInput_BaseStyle}"
|
Style="{DynamicResource NumberInput_BaseStyle}"
|
||||||
Value="{Binding Value, ElementName=Slider_Zoom}" />
|
Value="{Binding Value, ElementName=Slider_Zoom}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -49,20 +49,16 @@
|
|||||||
Command="{Binding PlacementTarget.Tag.SaveSettingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
Command="{Binding PlacementTarget.Tag.SaveSettingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
||||||
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
||||||
Header="{ll:Str 保存}" />
|
Header="{ll:Str 保存}" />
|
||||||
|
<MenuItem
|
||||||
|
Command="{Binding PlacementTarget.Tag.ResetSettingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
||||||
|
CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
||||||
|
Header="{ll:Str 重置}" />
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
</ListBox.ItemContainerStyle>
|
</ListBox.ItemContainerStyle>
|
||||||
</ListBox>
|
</ListBox>
|
||||||
<Button
|
|
||||||
Grid.Row="2"
|
|
||||||
Margin="0"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
Command="{Binding ResetSettingCommand}"
|
|
||||||
Content="{ll:Str 重置选中的设置}"
|
|
||||||
IsEnabled="{Binding SelectedItem, ElementName=ListBox_Saves, Converter={StaticResource NullToFalse}}"
|
|
||||||
Style="{DynamicResource Button_BaseStyle}" />
|
|
||||||
<Button
|
<Button
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
Margin="0"
|
Margin="0"
|
||||||
@ -71,7 +67,7 @@
|
|||||||
Content="{ll:Str 全部保存}"
|
Content="{ll:Str 全部保存}"
|
||||||
Style="{DynamicResource Button_BaseStyle}" />
|
Style="{DynamicResource Button_BaseStyle}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Column="1">
|
<Grid Grid.Column="1" IsEnabled="{Binding SelectedItem, ElementName=ListBox_Saves, Converter={StaticResource NullToFalse}}">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition />
|
<RowDefinition />
|
||||||
|
Loading…
Reference in New Issue
Block a user