2016-02-07 131 views
0

我遇到了Slider控件值不符合綁定到的支持屬性值的問題。這是一個錯誤,還是我做錯了什麼?UWP C#/ XAML Slider值不支持綁定的支持屬性

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

如果它是一個錯誤,沒有人知道一個解決辦法,確保滑塊的值可以去沒有比高支持價值?

問候......

回答

2

對於綁定需要注意的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二傳手:

set 
{ 
    NewCharacter.CharacterDefense = value; 
    CalculateCharacterPointsRemaining(); 
} 
+0

非常感謝您FO你的解釋。我之前設置了最大值,但遇到了一些挑戰,需要創建另一個支持屬性,這將結合當前點的數量加上可用的,我不願意做的。但是,現在您的答案爲我節省了繼續使用setter進行值綁定的時間。謝謝。一個問題,如果我可能會進一步打擾你......爲什麼將調度程序傳遞到VM通常是一個糟糕的主意? – RAB

+0

@RAB將調度程序傳遞給視圖模型會使視圖模型的單元測試更加困難,並會創建對特定調度程序實現的依賴關係,從而限制代碼對其他平臺的可移植性。您可以通過在每個平臺上可能有不同實現的服務接口中包裝對調度程序的訪問來減輕這兩個問題,並且可以在單獨測試中沒有真正調度程序的情況下單獨執行調度程序。儘管如此,它會增加代碼的複雜性,所以如果可能的話,我會避免它。 –

+0

請允許我再次感謝你。有一些複雜性,因爲OnPropertyChanged過早地關閉了值,所以我將它們全部放在它們自己的屏幕更新方法中並解決了問題。你的回答是最有幫助的! – RAB