我正在回答这个问题,但在回答过程中发现了很多奇怪的行为。由于我支持MVVM,我组合了一个解决方案,以查看是否会出现相同的行为。我的解决方案揭示了一个问题,即使我将
TwoWay
绑定到Slider.Value
,在Slider.Maximum
和Slider.Minimum
更改后,它不会在我的ViewModel中更新;也就是说,我的ViewModel的Value
可能在UpperLimit
和LowerLimit
之外,同时Slider.Value
(我的VM的Value
属性绑定到)在范围内。
在上述问题中,更改Slider.Maximum
或Slider.Minimum
似乎总是保持Slider.Value
在范围内,并有时“恢复”Slider.Value
到先前设置的值。
- 为什么
Slider.Value
会像链接的问题中看到的那样更改/恢复其值,即使当前值在Min/Max范围内? - 为什么更改
UpperLimit
和LowerLimit
后,我的绑定到Slider.Value
的视图模型的Value
属性不匹配TwoWay
绑定?- 请注意,最大值和最小值的绑定有效
MainWindow.xaml:
<DockPanel>
<Slider Name="MySlider" DockPanel.Dock="Top" AutoToolTipPlacement="BottomRight" Value="{Binding Value, Mode=TwoWay}" Maximum="{Binding UpperLimit}" Minimum="{Binding LowerLimit}"/>
<Button Name="MyButton1" Click="MyButton1_Click" DockPanel.Dock="Top" Content="shrink borders"/>
<Button Name="MyButton2" Click="MyButton2_Click" DockPanel.Dock="Top" VerticalAlignment="Top" Content="grow borders"/>
<Button Name="MyButton3" Click="MyButton3_Click" DockPanel.Dock="Top" VerticalAlignment="Top" Content="Print ItemVM Value"/>
</DockPanel>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
private readonly ItemViewModel item;
public MainWindow()
{
InitializeComponent();
DataContext = item = new ItemViewModel(new Item(1, 20, 0.5));
}
private void MyButton1_Click(object sender, RoutedEventArgs e)
{
//MySlider.Minimum = 1.6;
//MySlider.Maximum = 8;
item.LowerLimit = 1.6;
item.UpperLimit = 8;
}
private void MyButton2_Click(object sender, RoutedEventArgs e)
{
//MySlider.Minimum = 0.5;
//MySlider.Maximum = 20;
item.LowerLimit = 0.5;
item.UpperLimit = 20;
}
private void MyButton3_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Item Value: " + item.Value);
System.Diagnostics.Debug.WriteLine("Slider Value: " + MySlider.Value);
}
}
项目/项目视图模型:
public class ItemViewModel : INotifyPropertyChanged
{
private readonly Item _item;
public event PropertyChangedEventHandler PropertyChanged;
public ItemViewModel(Item item)
{
_item = item;
}
public double UpperLimit
{
get
{
return _item.UpperLimit;
}
set
{
_item.UpperLimit = value;
NotifyPropertyChanged();
}
}
public double LowerLimit
{
get
{
return _item.LowerLimit;
}
set
{
_item.LowerLimit = value;
NotifyPropertyChanged();
}
}
public double Value
{
get
{
return _item.Value;
}
set
{
_item.Value = value;
NotifyPropertyChanged();
}
}
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Item
{
private double _value;
private double _upperLimit;
private double _lowerLimit;
public double Value
{
get
{
return _value;
}
set
{
_value = value;
}
}
public double UpperLimit
{
get
{
return _upperLimit;
}
set
{
_upperLimit = value;
}
}
public double LowerLimit
{
get
{
return _lowerLimit;
}
set
{
_lowerLimit = value;
}
}
public Item(double value, double upperLimit, double lowerLimit)
{
_value = value;
_upperLimit = upperLimit;
_lowerLimit = lowerLimit;
}
}
重现步骤:
点击
MyButton3
项目值 = 1
滑块值 = 1
将滑块/拇指移至最右侧
点击
MyButton3
项目值 = 20
滑块值 = 20
点击
MyButton1
点击
MyButton3
项目值 = 20
滑块值 = 8
如果在 MyButton3_Click
中设置断点并执行最后一步,您会发现 MySlider.Value = 8