2010-12-17 60 views
8

我遇到了使用雙向綁定與listpicker的問題。我可以使用c#設置值,但不能在xaml的SelectedItem=".."中設置。綁定正在返回正確的值(並且是listpicker中的一個值),因爲我通過將文本分配給文本塊來發短信。雙向綁定設置問題

頁面加載後,綁定的listpicker使用導致System.ArgumentOutOfRangeException

我使用的設置它的代碼是:

// Update a setting value. If the setting does not exist, add the setting. 
    public bool AddOrUpdateValue(string key, Object value) 
    { 
     bool valueChanged = false; 

     try 
     { 
      // If new value is different, set the new value 
      if (settingsStorage[key] != value) 
      { 
       settingsStorage[key] = value; 
       valueChanged = true; 
      } 
     } 
     catch (KeyNotFoundException) 
     { 
      settingsStorage.Add(key, value); 
      valueChanged = true; 
     } 
     catch (ArgumentException) 
     { 
      settingsStorage.Add(key, value); 
      valueChanged = true; 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("Exception occured whilst using IsolatedStorageSettings: " + e.ToString()); 
     } 

     return valueChanged; 
    } 


    // Get the current value of the setting, if not found, set the setting to default value. 
    public valueType GetValueOrDefault<valueType>(string key, valueType defaultValue) 
    { 
     valueType value; 

     try 
     { 
      value = (valueType)settingsStorage[key]; 
     } 
     catch (KeyNotFoundException) 
     { 
      value = defaultValue; 
     } 
     catch (ArgumentException) 
     { 
      value = defaultValue; 
     } 

     return value; 
    } 

    public string WeekBeginsSetting 
    { 
     get 
     { 
      return GetValueOrDefault<string>(WeekBeginsSettingKeyName, WeekBeginsSettingDefault); 
     } 
     set 
     { 
      AddOrUpdateValue(WeekBeginsSettingKeyName, value); 
      Save(); 
     } 
    } 

而在XAML:

<toolkit:ListPicker x:Name="WeekStartDay" 
        Header="Week begins on" 
        SelectedItem="{Binding Source={StaticResource AppSettings}, 
              Path=WeekBeginsSetting, 
              Mode=TwoWay}"> 
    <sys:String>monday</sys:String> 
    <sys:String>sunday</sys:String> 
</toolkit:ListPicker> 

StaticResource AppSettings是來自單獨的.cs文件的資源。

<phone:PhoneApplicationPage.Resources> 
    <local:ApplicationSettings x:Key="AppSettings"></local:ApplicationSettings> 
</phone:PhoneApplicationPage.Resources> 

在此先感謝

+0

當你寫'{StaticResource AppSettings}'時,你是什麼意思?它是''XAML'或'static class'中定義的'resource'的名字嗎? – decyclone 2010-12-17 16:23:06

+0

對不起,我忘了提及AppSettings是一個單獨的類文件 – Jamie 2010-12-17 16:35:54

+0

它是一個靜態類嗎?您是否將當前綁定與{x:Static AppSettings.WeekBeginsSetting}混淆?因爲Silverlight不支持'{x:Static}'。 – decyclone 2010-12-17 16:40:25

回答

5

我用反射器找到這個異常的來源。在ListPicker.cs中,以下方法被覆蓋。

protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e) 

在該方法中下面的行會引起異常,如果的SelectedItem設置和的SelectedIndex是-1(它是除非它的加載之前將其設置)。如果SelectedItem沒有設置,那麼這條線永遠不會到達(因此也不例外)。

else if (!object.Equals(base.get_Items().get_Item(this.SelectedIndex), this.SelectedItem)) 

要解決此問題(直到他們得到此固定)我有一些建議。

解決方法1

如果你知道這將是由雙向綁定,那麼你可以設置SelectedIndex屬性以及和雙向綁定將工作

<toolkit:ListPicker x:Name="WeekStartDay" 
        Header="Week begins on" 
        SelectedItem="{Binding Source={StaticResource AppSettings}, 
              Path=WeekBeginsSetting, 
              Mode=TwoWay}" 
        SelectedIndex="1"> 
    <sys:String>monday</sys:String> 
    <sys:String>sunday</sys:String> 
</toolkit:ListPicker> 

解決方法生產的起始索引2

使用Loaded事件並從那裏設置Binding

<toolkit:ListPicker x:Name="WeekStartDay" 
        Header="Week begins on" 
        Loaded="WeekStartDay_Loaded"> 
    <sys:String>monday</sys:String> 
    <sys:String>sunday</sys:String> 
</toolkit:ListPicker> 

private void WeekStartDay_Loaded(object sender, RoutedEventArgs e) 
{ 
    Binding binding = new Binding(); 
    binding.Source = this.Resources["AppSettings"] as ApplicationSettings; 
    binding.Path = new PropertyPath("WeekBeginsSetting"); 
    binding.Mode = BindingMode.TwoWay; 
    WeekStartDay.SetBinding(ListPicker.SelectedItemProperty, binding); 
} 
+0

thx詳細看這個。我想我會採用解決方法#2。 – Stan 2010-12-28 20:18:59

0

你射擊的相關屬性更改的事件?

確保SelectedItem可以有雙向綁定。如果沒有,然後嘗試定義一個ItemContainerStyle並將IsSelected屬性綁定到對象上的對應屬性。獲取所選項然後變得微不足道。

+0

糟糕,我忘記提及我遇到的問題是當設置listpicker它引發'System.ArgumentOutOfRangeException' – Jamie 2010-12-17 18:20:40

0

如果AppSettings是一個集合,那麼這是行不通的。您需要將SelectedItem綁定到標量值,不幸的是,WP7上的「Silverlight 3.7」不支持綁定中的索引器。

另外,請不要使用異常流量控制在你的程序,而不是做這樣的事情:

try 
    { 
     // If new value is different, set the new value 
     if(!settingsStorage.ContainsKey(key)) 
     { 
      settingsStorage.Add(key, value); 
      valueChanged = true; 
     } 
     else if(settingsStorage[key] != value) 
     { 
      settingsStorage[key] = value; 
      valueChanged = true; 
     } 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine("Exception occured whilst using IsolatedStorageSettings: " + e.ToString()); 
    } 
+0

謝謝,我可以讓SelectedIndex工作,但它只是突出顯示該項目,並不顯示它時,列表選擇器是非活動 - 顯示列表選取器中的第一個值。 – Jamie 2010-12-17 23:05:41

0

而不是使用綁定我簡單地設置selectedItem屬性加載頁面時,並使用SelectionChanged事件處理程序無需確認即可更新值(具有保存按鈕)。