我遇到了一个问题,Slider控件值不符合它绑定的backing属性的值。这是一个错误,还是我做错了什么?
XAML代码:
<Slider x:Name="DefenseSlider" Width="220" StepFrequency="1"
Minimum="0"
Maximum="10"
Value="{Binding CharacterDefense, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
C#支持代码:
public int CharacterDefense
{
get { return NewCharacter.CharacterDefense; }
set
{
CalculateCharacterPointsRemaining();
if (value <= CharacterPointsAvailable)
{
NewCharacter.CharacterDefense = value;
}
if (value > CharacterPointsAvailable)
{
NewCharacter.CharacterDefense = CharacterPointsAvailable;
}
CalculateCharacterPointsRemaining();
}
}
如果是错误,有没有人知道解决方法,以确保滑块的值不高于支持值?
...问候
答案 0 :(得分:3)
要使绑定知道CharacterDefense
属性更改,您需要引发PropertyChanged
接口的INotifyPropertyChanged
事件。
set
{
CalculateCharacterPointsRemaining();
if (value <= CharacterPointsAvailable)
{
NewCharacter.CharacterDefense = value;
}
if (value > CharacterPointsAvailable)
{
NewCharacter.CharacterDefense = CharacterPointsAvailable;
}
CalculateCharacterPointsRemaining();
OnPropertyChanged();
}
但是,如果在绑定本身触发的属性setter调用中引发了绑定,则绑定会忽略该事件。要使其工作,您需要将事件发送到调度程序队列的末尾:
set
{
CalculateCharacterPointsRemaining();
if (value <= CharacterPointsAvailable)
{
NewCharacter.CharacterDefense = value;
}
if (value > CharacterPointsAvailable)
{
NewCharacter.CharacterDefense = CharacterPointsAvailable;
}
CalculateCharacterPointsRemaining();
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
OnPropertyChanged(nameof(CharacterDefense)));
}
Dispatcher
是Page
类的属性,除非您从视图中传递它,否则您将无法在视图模型中访问它。虽然你可以这样做,但通常是一个坏主意。
Slider
控件有Maximum
属性是有原因的。如果要动态限制允许的值范围,则应添加返回CharacterPointsAvailable
的视图模型属性。当然,每当此值发生变化时,您需要RaisePropertyChanged
通知绑定它应该更新值:
public int MaxCharacterDefense
{
get { return CharacterPointsAvailable; }
}
private void CharacterPointsAvailable()
{
// ... existing method logic
OnPropertyChanged(nameof(MaxCharacterDefense));
}
现在可以将滑块绑定到此属性:
<Slider x:Name="DefenseSlider" Width="220" StepFrequency="1"
Minimum="0"
Maximum="{Binding MaxCharacterDefense}"
Value="{Binding CharacterDefense, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
现在,该控件不再允许无效的值,因此您可以简化CharacterDefense
setter:
set
{
NewCharacter.CharacterDefense = value;
CalculateCharacterPointsRemaining();
}