Silverlight MVVM组合框绑定已损坏

Silverlight MVVM组合框绑定已损坏,silverlight,data-binding,mvvm,silverlight-4.0,combobox,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

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

<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中定义了两个属性,RoomList是List,Room属性是string

当我第一次运行应用程序时,一切正常,下拉菜单获得正确的值,并且选择了正确的值。但是,在特定条件下,RoomList属性会更改为其他源&Room属性也会更改。现在出现的问题是,组合框显示了正确的值,但所选值未被选中。更糟糕的是,我们可以接受这种情况,但是当在下拉列表中手动更改值时,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; }
}

公共主页()
{
初始化组件();
此.Loaded+=(s,e)=>
{
var temp=新列表();
临时添加(新绑定(){code=“1”,display=“One”});
临时添加(新绑定(){code=“2”,display=“Two”});
this.ComboSource=temp;
this.ComboSelection=“1”;
this.DataContext=this;
};
}
私有静态只读DependencyProperty ComboSelectionProperty=
Register(“ComboSelectionProperty”、typeof(string)、typeof(MainPage)、new PropertyMetadata(null));
公共字符串组合选择
{
get{return(string)GetValue(ComboSelectionProperty);}
设置
{ 
SetValue(ComboSelectionProperty,value);
此.RaisePropertyChanged(“组合选择”);
}
}
私有静态只读DependencyProperty ComboSourceProperty=
Register(“ComboSourceProperty”、typeof(List)、typeof(MainPage)、newpropertyMetadata(null));
公共列表组合源
{
得到
{
返回(列表)GetValue(ComboSourceProperty);
}
设置
{
SetValue(ComboSourceProperty,value);
此.RaisePropertyChanged(“ComboSource”);
}
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
var temp=新列表();
临时添加(新绑定(){code=“3”,display=“Three”});
临时添加(新绑定(){code=“4”,display=“Four”});
this.ComboSource=temp;
this.ComboSelection=“3”;
}
#区域INotifyProperty更改成员
公共事件属性更改事件处理程序属性更改;
私有void RaisePropertyChanged(字符串propertyName)
{
if(this.PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
#端区
}
公共类绑定
{
公共字符串代码{get;set;}
公共字符串显示{get;set;}
}

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

您的
SelectedValuePath
是“显示”,我假设它是
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}"/>

组合框数据绑定中似乎存在缺陷,如果绑定到SelectedValue的数据变为null,则绑定将完全中断

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

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

另一方面,您可能不需要使用依赖项属性来支持ComboSelection。只要您继续使用PropertyChanged,此属性的数据绑定在普通属性上应该可以正常工作。

为上述问题添加了后续部分。