双向绑定设置问题

时间:2010-12-17 16:17:51

标签: c# silverlight xaml windows-phone-7

我在使用与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>

提前致谢

4 个答案:

答案 0 :(得分:5)

我使用Reflector查找此异常的来源。在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

如果您知道将由TwoWay绑定生成的起始索引,那么您也可以设置SelectedIndex属性并且TwoWay绑定将起作用

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

答案 1 :(得分:0)

您是否正在解雇相关的财产变更事件?

确保SelectedItem可以具有双向绑定。如果没有,则尝试定义ItemContainerStyle并将IsSelected属性绑定到对象上的相应属性。获取所选项目然后变得微不足道。

答案 2 :(得分: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());
    }

答案 3 :(得分:0)

我没有使用绑定,而是在加载页面时设置selecteditem,并使用selectionchanged事件处理程序更新值而不进行确认(具有保存按钮)。