Silverlight MVVM Combobox绑定破碎

时间:2010-10-01 13:20:08

标签: 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会被更改,并且会进行新的选择,但是这个选择没有绑定,我上面提到的问题就开始发生了。

1 个答案:

答案 0 :(得分:1)

不确定您的实际源代码,但在您的示例中,您的依赖注册不太正确。

应该是:

DependencyProperty.Register("ComboSelection"

DependencyProperty.Register("ComboSource"

不是“xxxProperty”。然后它全部正确地激发了变化。

基本上,您正在注册依赖项对象本身,而不是get / set属性方法。参数文档/命名可能看起来有点误导。

*注意:根据Dan Bryant的评论 - 也不需要INotifyPropertyChange的内容,我将其从您的示例代码中删除(我可以向您保证,如果没有它,它可以完美地运行)。