UWP 和 ReactiveUI – 我(有时)如何同步两个滑块值?
UWP and ReactiveUI – How do I (sometimes) synchronise two sliders values?
在我的 XAML 中,我有两个滑块和一个切换按钮:
<Slider
x:Name="rightSlider"
Header="Right"
Maximum="20"
Minimum="0" />
<Slider
x:Name="suffixSlider"
Header="Suffix"
Maximum="20"
Minimum="0" />
<ToggleButton
x:Name="toggleSuffixLockButton"
Content="Lock" />
在我后面的视图代码中,我将它们绑定如下:
this.Bind(ViewModel,
viewModel => viewModel.RightSliderValue,
view => view.rightSlider.Value)
.DisposeWith(disposableRegistration);
this.Bind(ViewModel,
viewModel => viewModel.SuffixSliderValue,
view => view.suffixSlider.Value)
DisposeWith(disposableRegistration);
this.OneWayBind(ViewModel,
viewModel => viewModel.SuffixIsLocked,
view => view.suffixSlider.IsEnabled,
value => value == false ? true : false)
.DisposeWith(disposableRegistration);
this.Bind(ViewModel,
viewModel => viewModel.SuffixIsLocked,
view => view.toggleSuffixLockButton.IsChecked)
.DisposeWith(disposableRegistration);
我的视图模型有这些声明:
[Reactive]
public double RightSliderValue { get; set; }
[Reactive]
public double SuffixSliderValue { get; set; }
[Reactive]
public bool SuffixIsLocked { get; set; }
未选中 toggleSuffixLockButton 时,用户应该能够独立更改两个滑块;这有效。
未选中 toggleSuffixLockButton 时,我希望启用 suffixSlider 元素;这有效。
选中toggleSuffixLockButton 后,我希望禁用suffixSlider 元素;这有效。
但是,一旦选中 toggleSuffixLockButton,我还希望立即将 suffixSlider 值设置为 rightSlider 的值,然后每次 rightSlider 更改时(选中 toggleSuffixLockButton 时),suffixSlider 也应更改为相同的值, 直到未选中 toggleSuffixLockButton;我不知道该怎么做。
我本来对如何做有一个模糊的想法,但我开始兜圈子。
有人能帮忙吗?
添加了额外的代码(在视图模型中)以显示“双重处理”的额外问题:
private readonly ObservableAsPropertyHelper<string> _theResult;
public string TheResult => _theResult.Value;
_theResult = this
.WhenAnyValue(
viewModel => viewModel.RightSliderValue,
viewModel => viewModel.SuffixSliderValue,
(right, suffix) => new GenerationParameters(right, suffix))
// .Throttle(TimeSpan.FromMilliseconds(200))
.DistinctUntilChanged()
.SelectMany(GetResult) // GetResult simply returns a string based on the right and suffix values.
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.TheResult, String.Empty);
每当锁定打开时(根据下面提供的代码),_theResult 都会针对 RightSliderValue 更改和 SuffixSliderValue 更改重新计算,一个接一个地进行(或者可能同时进行,因为它是异步的,我是不确定)。
当 .Throttle() 代码取消注释时(因为我将在我的实际应用程序中使用它)没有问题,但我想知道是否有一种方法不必限制它(以防万一我需要在未来的项目中这样做)。
我会将其逻辑添加到视图模型中,以便视图仅包含绑定。它应该在视图模型构造函数中使用这两个 WhenAnyValue
语句来工作。 WhenActivated
块:
// sets the suffix slider to the position of right slider
// if suffix gets locked
this.WhenAnyValue(x => x.SuffixIsLocked)
.Where(locked => locked)
.Subscribe(_ => SuffixSliderValue = RightSliderValue);
// keeps both sliders in sync if suffix is locked
this.WhenAnyValue(x => x.RightSliderValue)
.Where(_ => SuffixIsLocked)
.Subscribe(_ => SuffixSliderValue = RightSliderValue);
// second part: GetResult
// observable for right slider if not SuffixIsLocked
IObservable<GenerationParameters> parametersFromRight = this
.WhenAnyValue(
viewModel => viewModel.RightSliderValue,
(right) => new GenerationParameters(right, SuffixSliderValue))
.Where(_ => !SuffixIsLocked);
// observable for suffix slider
IObservable<GenerationParameters> parametersFromSuffix = this
.WhenAnyValue(
viewModel => viewModel.SuffixSliderValue,
(suffix) => new GenerationParameters(RightSliderValue, suffix));
// merge and create property
_theResult = parametersFromRight
.Merge(parametersFromSuffix)
.DistinctUntilChanged()
.SelectMany(GetResult)
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.TheResult, string.Empty);
// catch exceptions
_theResult.ThrownExceptions.Subscribe(ex => Console.WriteLine(ex.Message));
编辑:更新了问题第二部分的代码。
注意:这只会在合并后捕获异常,即 GetResult
中的异常,而不是 GenerationParameters
.
的构造函数中发生的异常
在我的 XAML 中,我有两个滑块和一个切换按钮:
<Slider
x:Name="rightSlider"
Header="Right"
Maximum="20"
Minimum="0" />
<Slider
x:Name="suffixSlider"
Header="Suffix"
Maximum="20"
Minimum="0" />
<ToggleButton
x:Name="toggleSuffixLockButton"
Content="Lock" />
在我后面的视图代码中,我将它们绑定如下:
this.Bind(ViewModel,
viewModel => viewModel.RightSliderValue,
view => view.rightSlider.Value)
.DisposeWith(disposableRegistration);
this.Bind(ViewModel,
viewModel => viewModel.SuffixSliderValue,
view => view.suffixSlider.Value)
DisposeWith(disposableRegistration);
this.OneWayBind(ViewModel,
viewModel => viewModel.SuffixIsLocked,
view => view.suffixSlider.IsEnabled,
value => value == false ? true : false)
.DisposeWith(disposableRegistration);
this.Bind(ViewModel,
viewModel => viewModel.SuffixIsLocked,
view => view.toggleSuffixLockButton.IsChecked)
.DisposeWith(disposableRegistration);
我的视图模型有这些声明:
[Reactive]
public double RightSliderValue { get; set; }
[Reactive]
public double SuffixSliderValue { get; set; }
[Reactive]
public bool SuffixIsLocked { get; set; }
未选中 toggleSuffixLockButton 时,用户应该能够独立更改两个滑块;这有效。
未选中 toggleSuffixLockButton 时,我希望启用 suffixSlider 元素;这有效。
选中toggleSuffixLockButton 后,我希望禁用suffixSlider 元素;这有效。
但是,一旦选中 toggleSuffixLockButton,我还希望立即将 suffixSlider 值设置为 rightSlider 的值,然后每次 rightSlider 更改时(选中 toggleSuffixLockButton 时),suffixSlider 也应更改为相同的值, 直到未选中 toggleSuffixLockButton;我不知道该怎么做。
我本来对如何做有一个模糊的想法,但我开始兜圈子。
有人能帮忙吗?
添加了额外的代码(在视图模型中)以显示“双重处理”的额外问题:
private readonly ObservableAsPropertyHelper<string> _theResult;
public string TheResult => _theResult.Value;
_theResult = this
.WhenAnyValue(
viewModel => viewModel.RightSliderValue,
viewModel => viewModel.SuffixSliderValue,
(right, suffix) => new GenerationParameters(right, suffix))
// .Throttle(TimeSpan.FromMilliseconds(200))
.DistinctUntilChanged()
.SelectMany(GetResult) // GetResult simply returns a string based on the right and suffix values.
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.TheResult, String.Empty);
每当锁定打开时(根据下面提供的代码),_theResult 都会针对 RightSliderValue 更改和 SuffixSliderValue 更改重新计算,一个接一个地进行(或者可能同时进行,因为它是异步的,我是不确定)。
当 .Throttle() 代码取消注释时(因为我将在我的实际应用程序中使用它)没有问题,但我想知道是否有一种方法不必限制它(以防万一我需要在未来的项目中这样做)。
我会将其逻辑添加到视图模型中,以便视图仅包含绑定。它应该在视图模型构造函数中使用这两个 WhenAnyValue
语句来工作。 WhenActivated
块:
// sets the suffix slider to the position of right slider
// if suffix gets locked
this.WhenAnyValue(x => x.SuffixIsLocked)
.Where(locked => locked)
.Subscribe(_ => SuffixSliderValue = RightSliderValue);
// keeps both sliders in sync if suffix is locked
this.WhenAnyValue(x => x.RightSliderValue)
.Where(_ => SuffixIsLocked)
.Subscribe(_ => SuffixSliderValue = RightSliderValue);
// second part: GetResult
// observable for right slider if not SuffixIsLocked
IObservable<GenerationParameters> parametersFromRight = this
.WhenAnyValue(
viewModel => viewModel.RightSliderValue,
(right) => new GenerationParameters(right, SuffixSliderValue))
.Where(_ => !SuffixIsLocked);
// observable for suffix slider
IObservable<GenerationParameters> parametersFromSuffix = this
.WhenAnyValue(
viewModel => viewModel.SuffixSliderValue,
(suffix) => new GenerationParameters(RightSliderValue, suffix));
// merge and create property
_theResult = parametersFromRight
.Merge(parametersFromSuffix)
.DistinctUntilChanged()
.SelectMany(GetResult)
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.TheResult, string.Empty);
// catch exceptions
_theResult.ThrownExceptions.Subscribe(ex => Console.WriteLine(ex.Message));
编辑:更新了问题第二部分的代码。
注意:这只会在合并后捕获异常,即 GetResult
中的异常,而不是 GenerationParameters
.