我有点进退两难。一段时间以来,我一直在为一个名为 SimHub 的应用程序开发一个插件,该插件在很大程度上可以工作。我正在进入一个阶段,我想不断改进它并添加更多功能。
我的插件的部分功能是设置一个在应用程序内部使用的属性值。此设置是在“设置页面”内完成的,当值更改时,它会更新 .json 文件中的条目。然后读取 .json 中的该条目并将其分配给一个属性。
我想要做的改进就是这个。您还可以添加“操作”,这是键盘快捷键的设置。然后该快捷方式将执行指定的操作。我试图添加的操作是 2 个键。一个键可将值增加 0.1,另一个键可将值减少 0.1。
我已成功添加该操作,它会增加或减少设置 .json 文件中的值,并且属性会更新。但我想要实现的是,当按键用于递增或递减值时,我也希望该值显示在设置屏幕中。
下面是相关代码。有一点还请大家见谅。我已经省略了所有不相关的内容。
主要代码
public class OMSCPlugin : IPlugin, IDataPlugin, IWPFSettings, IWPFSettingsV2
{
public OMSCPluginSettings Settings;
public void Init(PluginManager pluginManager)
{
Logging.Current.Info((object)($"Starting plugin: OMSC Plugin - Version {VersionText}"));
this.Settings = this.ReadCommonSettings<OMSCPluginSettings>("Settings", (Func<OMSCPluginSettings>)(() => new OMSCPluginSettings()));
this.AttachDelegate<OMSCPlugin, double>("Settings.ACC.FuelSafetyBuffer", (Func<double>)(() => this.Settings.ACCFuelSafetyBuffer));
this.AddAction("IncrementFSB", (a, b) =>
{
Settings.ACCFuelSafetyBuffer += 0.1;
this.SaveCommonSettings<OMSCPluginSettings>("Settings", this.Settings);
});
this.AddAction("DecrementFSB", (a, b) =>
{
Settings.ACCFuelSafetyBuffer -= 0.1;
this.SaveCommonSettings<OMSCPluginSettings>("Settings", this.Settings);
});
}
}
XAML(排除了一堆不相关的东西)
<UserControl x:Class="OzrickMajor.OMSCPlugin.OMSCPluginSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.microsoft.com/expression/blend/2008"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local1="clr-namespace:OzrickMajor.OMSCPlugin"
xmlns:local2="clr-namespace:OzrickMajor.OMSCPlugin.Sections"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:styles="clr-namespace:SimHub.Plugins.Styles;assembly=SimHub.Plugins"
xmlns:ui="clr-namespace:SimHub.Plugins.UI;assembly=SimHub.Plugins"
xmlns:wpfui="clr-namespace:SimHub.Plugins.OutputPlugins.Dash.WPFUI;assembly=SimHub.Plugins"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit">
<mah:NumericUpDown Grid.Row="1" Grid.Column="0" ValueChanged="ACCFuelSafetyBuffer_ValueChanged" x:Name="_accfuelsafetybuffer" Width="170"
Minimum="0.1" Maximum="5.0" Interval="0.1" StringFormat="0.0" HasDecimals="True" Cursor="Hand"/>
<Label Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Margin="5,0,0,0" FontWeight="Bold"
Content="Fuel Safety Buffer (in Laps)"/>
<ui:ControlsEditor Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" FriendlyName="Increment FSB" ActionName="OMSCPlugin.IncrementFSB"/>
<ui:ControlsEditor Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" FriendlyName="Decrement FSB" ActionName="OMSCPlugin.DecrementFSB"/>
XAML 代码背后
public partial class OMSCPluginSettingsControl : UserControl, IComponentConnector
{
public OMSCPlugin Plugin { get; }
public PluginManager PluginManager { get; internal set; }
public OMSCPluginSettingsControl()
{
this.InitializeComponent();
}
public OMSCPluginSettingsControl(OMSCPlugin plugin) : this()
{
this.Plugin = plugin;
this._accfuelsafetybuffer.Value = this.Plugin.Settings.ACCFuelSafetyBuffer;
}
public void ACCFuelSafetyBuffer_ValueChanged(object sender, EventArgs e)
{
this.Plugin.Settings.ACCFuelSafetyBuffer = Math.Round((double)this._accfuelsafetybuffer.Value, 1);
this.Plugin.SaveCommonSettings<OMSCPluginSettings>("Settings", this.Plugin.Settings);
}
}
设置文件代码
public class OMSCPluginSettings
{
public double ACCFuelSafetyBuffer { get; set; } = 1.5;
}
我尝试通过 xaml 的“Value”参数中的 {Binding Path=ACCFuelSafetyBuffer} 来实现我需要的功能,如下所示:
<mah:NumericUpDown Grid.Row="1" Grid.Column="0" ValueChanged="ACCFuelSafetyBuffer_ValueChanged" x:Name="_accfuelsafetybuffer" Width="170"
Minimum="0.1" Maximum="5.0" Interval="0.1" StringFormat="0.0" HasDecimals="True" Cursor="Hand"
Value="{Binding Path=ACCFuelSafetyBuffer}"/>
<Label Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Margin="5,0,0,0" FontWeight="Bold"
Content="Fuel Safety Buffer (in Laps)"/>
当我在应用程序中进行编译和检查时,该框只是空白,并且不显示该值,即使该值存在于设置文件中并且已应用于属性,并且在按下按键时仍然会发生变化。我的假设是我的绑定实际上不会去任何地方,因此,空白框,即使我没有收到任何编译器错误或运行时错误。
任何帮助将不胜感激。
我希望在不添加太多额外代码的情况下做到这一点,因为我最近的另一个目标是从我第一次开始学习 C# 和编写插件时减少很多不必要的代码。
OMSCPluginSettings
类应实现INotifyPropertyChanged
接口并引发PropertyChanged
属性的ACCFuelSafetyBuffer
事件以通知视图源属性已更改:
public class OMSCPluginSettings : INotifyPropertyChanged
{
private double _accFuelSafetyBuffer = 1.5;
public double ACCFuelSafetyBuffer
{
get { return _accFuelSafetyBuffer; }
set { _accFuelSafetyBuffer = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}