Silverlight MVVM Combobox绑定破碎

时间:2010-09-30 15:20:55

标签: silverlight data-binding mvvm silverlight-4.0 combobox

我有一个这样定义的组合框

<ComboBox Name="RoomDropDown" Visibility="{Binding Path=RoomDropDownVisible,Mode=OneWay,Converter={StaticResource BoolVisibilityConvertor}}"
                          ItemsSource="{Binding Path=RoomList,Mode=OneWay}" DisplayMemberPath="display" SelectedValuePath="display" SelectedValue="{Binding Path=Room,Mode=TwoWay}"/>

ViewModel中定义了2个属性,RoomList是List,Room属性是字符串。

第一次运行应用程序时,一切正常,Drop Down获取正确的值以及选择了正确的值。但是在某些条件下,RoomList属性会更改为不同的源和属性。房间也改变了。现在发生的问题是组合框显示正确的值,但未选择所选的值。更糟糕的是,我们可以接受这一点,但是当在DropDown中手动更改值时, setter 不会触发

关于这里出了什么问题的任何指示?

跟进: 不要以为我设法解决了确切的问题,这里有一些我想添加的示例代码来说明问题:

<Grid x:Name="LayoutRoot" Background="White">
    <StackPanel VerticalAlignment="Center" Width="100">
        <ComboBox Name="TestBox" Height="20" Width="100" ItemsSource="{Binding Path=ComboSource}" DisplayMemberPath="display" SelectedValuePath="code" 
                  SelectedValue="{Binding Path=ComboSelection,Mode=TwoWay}"/>
        <Button Content="Click Here" Click="Button_Click" />
    </StackPanel>
 </Grid>



public MainPage()
    {
        InitializeComponent();
        this.Loaded += (s, e) =>
            {
                var temp = new List<Binding>();
                temp.Add(new Binding() { code = "1", display = "One" });
                temp.Add(new Binding() { code = "2", display = "Two" });
                this.ComboSource = temp;
                this.ComboSelection = "1";
                this.DataContext = this;
            };
    }

    private static readonly DependencyProperty ComboSelectionProperty =
        DependencyProperty.Register("ComboSelectionProperty", typeof(string), typeof(MainPage), new PropertyMetadata(null));

    public string ComboSelection
    {
        get { return (string)GetValue(ComboSelectionProperty); }
        set 
        { 
            SetValue(ComboSelectionProperty, value);
            this.RaisePropertyChanged("ComboSelection");
        }
    }

    private static readonly DependencyProperty ComboSourceProperty =
        DependencyProperty.Register("ComboSourceProperty", typeof(List<Binding>), typeof(MainPage), new PropertyMetadata(null));

    public List<Binding> ComboSource
    {
        get
        {
            return (List<Binding>)GetValue(ComboSourceProperty);
        }
        set
        {
            SetValue(ComboSourceProperty, value);
            this.RaisePropertyChanged("ComboSource");
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var temp = new List<Binding>();
        temp.Add(new Binding() { code = "3", display = "Three" });
        temp.Add(new Binding() { code = "4", display = "Four" });

        this.ComboSource = temp;
        this.ComboSelection = "3";

    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
 }

 public class Binding
{
    public string code {get; set;}
    public string display { get; set; }
}

不是严格意义上的MVVM,但为了解释这个问题,当按钮点击事件被触发时,Combosource会被更改,并且会进行新的选择,但是这个选择没有绑定,我上面提到的问题就开始发生了。

2 个答案:

答案 0 :(得分:2)

你的SelectedValuePath是“display”,我假设它是Room类的字符串属性。但是您将SelectedValue绑定到viewmodel的Room属性,并且我假设此属性的类型为Room ...所以SelectedValue的类型为字符串,并且您将它绑定到Room类型的属性:它无法工作,因为这些类型之间没有转换。

为什么不使用SelectedValue

,而不是使用SelectedItem属性
<ComboBox Name="RoomDropDown" Visibility="{Binding Path=RoomDropDownVisible,Mode=OneWay,Converter={StaticResource BoolVisibilityConvertor}}"
          ItemsSource="{Binding Path=RoomList,Mode=OneWay}" DisplayMemberPath="display" SelectedItem="{Binding Path=Room,Mode=TwoWay}"/>

答案 1 :(得分:0)

ComboBox数据绑定中似乎存在一个错误,如果绑定到SelectedValue的数据变为空,绑定将完全中断。

在ComboSelection setter中放置一个断点,看看它是否被设置为null。如果这是问题的根源,请将其添加到您的setter:

public string ComboSelection
{
    // .....
    set
    {
        if(value == null)
            return;
        // .....
    }
}

另外,您可能不需要使用依赖项属性来支持ComboSelection。只要你继续使用PropertyChanged,对它的数据绑定就可以在普通属性上正常工作。