UWP C#/ XAML Slider Value不支持绑定的后备属性

时间:2016-02-07 09:21:56

标签: c# xaml slider uwp

我遇到了一个问题,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();
        }
    }

如果是错误,有没有人知道解决方法,以确保滑块的值不高于支持值?

...问候

1 个答案:

答案 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)));
}

DispatcherPage类的属性,除非您从视图中传递它,否则您将无法在视图模型中访问它。虽然你可以这样做,但通常是一个坏主意

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();
}