Привязка Combobox Silverlight MVVM разорвана - PullRequest
2 голосов
/ 30 сентября 2010

У меня есть поле со списком, определенное как таковое

<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, которое представляет собой строку.

В первый раз, когда я запускаю приложение, все работает нормально, и выпадающий список получает правильные значения, а также выбираются правильные значения. Однако при определенных условиях свойство RoomList изменяется на другой источник, а свойство Room также изменяется. Проблема, которая сейчас возникает, состоит в том, что в комбинированном окне отображаются правильные значения, но выбранное значение не выбирается. Хуже того, мы можем жить с этим, но установщик также не запускает , когда значение вручную изменяется в DropDown.

Есть какие-нибудь указатели на то, что здесь происходит не так?

Followup: Не думаю, что мне удалось разобраться с точной проблемой, вот пример кода, который я хотел бы добавить, чтобы проиллюстрировать проблему:

<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 ]

2 голосов
/ 30 сентября 2010

Ваш SelectedValuePath - это "display", который, как я полагаю, является строковым свойством класса Room.Но вы связываете SelectedValue со свойством Room вашей модели представления, и я предполагаю, что это свойство имеет тип Room ... Таким образом, SelectedValue имеет тип string, и вы связываете его ссвойство типа 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}"/>
0 голосов
/ 02 марта 2011

Кажется, что есть ошибка в привязке данных ComboBox, когда привязка полностью обрывается, если данные, которые она привязывает к SelectedValue, становятся нулевыми.

Поместите точку останова в установщик ComboSelection и посмотрите, будет ли она когда-либо полученаустановить на ноль.Если это является источником проблемы, добавьте это к своему установщику:

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

На заметку, вам, вероятно, не нужно использовать свойство зависимостей для поддержки ComboSelection.Привязка данных для этого должна нормально работать с обычным свойством, если вы продолжаете использовать PropertyChanged.

...