【发布时间】:2015-11-10 17:09:40
【问题描述】:
我在回答 this 问题时,我发现了很多奇怪的行为。因为我是支持 MVVM 的,所以我整理了一个解决方案,看看我是否会看到相同的行为。我的解决方案发现,即使我将TwoWay 绑定到Slider.Value,在Slider.Maximum 和Slider.Minimum 更改之后,它也不会在我的ViewModel 中更新;即我的视图模型的Value 可以在UpperLimit 和LowerLimit 之外,同时Slider.Value(我的VM 的Value 属性绑定到)在范围内。
在上述问题中,更改Slider.Maximum 或Slider.Minimum 似乎总是将Slider.Value 保持在范围内,有时会将Slider.Value“恢复”为之前设置的值。
Microsoft's Slider Source Code
-
为什么即使当前值在最小/最大范围内,
Slider.Value也会更改/恢复其值,如链接问题中所示? -
为什么在更改
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);
}
}
Item/ItemViewModel:
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
【问题讨论】: