Подтвердить что ты не робот

ComboBox.SelectedValue не обновляется из источника привязки

Здесь мой объект источника привязки:

Public Class MyListObject

    Private _mylist As New ObservableCollection(Of String)
    Private _selectedName As String

    Public Sub New(ByVal nameList As List(Of String), ByVal defaultName As String)

        For Each name In nameList
            _mylist.Add(name)
        Next

        _selectedName = defaultName

    End Sub

    Public ReadOnly Property MyList() As ObservableCollection(Of String)
        Get
            Return _mylist
        End Get
    End Property

    Public ReadOnly Property SelectedName() As String
        Get
            Return _selectedName
        End Get
    End Property

End Class

Вот мой XAML:

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300"
    xmlns:local="clr-namespace:WpfApplication1"
        >

    <Window.Resources>
        <ObjectDataProvider x:Key="MyListObject" ObjectInstance="" />
    </Window.Resources>

        <Grid>

        <ComboBox Height="23"
                  Margin="24,91,53,0"
                  Name="ComboBox1"
                  VerticalAlignment="Top"
                  SelectedValue="{Binding Path=SelectedName, Source={StaticResource MyListObject}, Mode=OneWay}"
                  ItemsSource="{Binding Path=MyList, Source={StaticResource MyListObject}, Mode=OneWay}"
                  />

        <Button Height="23"
                HorizontalAlignment="Left"
                Margin="47,0,0,87"
                Name="btn_List1"
                VerticalAlignment="Bottom"
                Width="75">List 1</Button>

        <Button Height="23"
                Margin="0,0,75,87"
                Name="btn_List2"
                VerticalAlignment="Bottom"
                HorizontalAlignment="Right"
                Width="75">List 2</Button>
    </Grid>
</Window>

Здесь код:

Class Window1

    Private obj1 As MyListObject
    Private obj2 As MyListObject
    Private odp As ObjectDataProvider

    Public Sub New()

        InitializeComponent()

        Dim namelist1 As New List(Of String)
        namelist1.Add("Joe")
        namelist1.Add("Steve")
        obj1 = New MyListObject(namelist1, "Steve")
.
        Dim namelist2 As New List(Of String)
        namelist2.Add("Bob")
        namelist2.Add("Tim")
        obj2 = New MyListObject(namelist2, "Tim")

        odp = DirectCast(Me.FindResource("MyListObject"), ObjectDataProvider)
        odp.ObjectInstance = obj1

    End Sub

    Private Sub btn_List1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btn_List1.Click

        odp.ObjectInstance = obj1

    End Sub

    Private Sub btn_List2_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btn_List2.Click

        odp.ObjectInstance = obj2

    End Sub
End Class

Когда окно сначала загружается, привязки прекрасно соединяются. ComboBox содержит имена "Joe" и "Steve", а "Steve" выбран по умолчанию. Однако, когда я нажимаю кнопку, чтобы переключить ObjectInstance в obj2, ComboBox ItemsSource правильно заполняется в раскрывающемся списке, но в SelectedValue установлено значение Nothing вместо того, чтобы быть равно obj2.SelectedName.

4b9b3361

Ответ 1

У нас была аналогичная проблема на прошлой неделе. Это связано с тем, как SelectedValue обновляет свои внутренние функции. Мы обнаружили, что если вы установите SelectedValue, он не увидит изменения, которые мы должны были установить вместо SelectedItem, которые должным образом обновили бы все. Я пришел к выводу, что SelectedValue предназначен для операций, а не установлен. Но это может быть просто ошибкой в ​​текущей версии 3.5sp1.net

Ответ 2

Чтобы разжечь двухлетний разговор:

Другая возможность, если вы хотите использовать строки, - привязать ее к свойству Text в поле со списком.

<ComboBox Text="{Binding Test}">
     <ComboBoxItem Content="A" />
     <ComboBoxItem Content="B" />
     <ComboBoxItem Content="C" />
</ComboBox>

Это связано с чем-то вроде:

public class TestCode
{
    private string _test;
    public string Test 
    { 
      get { return _test; }
      set
      {
         _test = value;
         NotifyPropertyChanged(() => Test); // NotifyPropertyChanged("Test"); if not using Caliburn
      }
    }
}

Приведенный выше код является двухсторонним, поэтому, если вы установите Test = "B"; в коде, тогда combobox покажет "B", а затем, если вы выберете "A" из выпадающего списка, свойство bound будет отражать это изменение.

Ответ 3

Используйте

UpdateSourceTrigger=PropertyChanged 

в привязке

Ответ 4

Проблема:

Класс ComboBox выполняет поиск указанного объекта с помощью метода IndexOf. Этот метод использует метод Equals для определения равенства.

Решение:

Итак, попробуйте установить SelectedIndex с помощью SelectedValue через Converter следующим образом:

Код С#

//Converter

public class SelectedToIndexConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null && value is YourType)
            {
                YourType YourSelectedValue = (YourType) value;

                YourSelectedValue = (YourType) cmbDowntimeDictionary.Tag;
                YourType a = (from dd in Helper.YourType
                                        where dd.YourTypePrimaryKey == YourSelectedValue.YourTypePrimaryKey
                                        select dd).First();

                int index = YourTypeCollection.IndexOf(a); //YourTypeCollection - Same as ItemsSource of ComboBox
            }
            return null;
        }
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value!=null && value is int)
            {
                return YourTypeCollection[(int) value];
            }

            return null;
        }
    }

Xaml

<ComboBox 
   ItemsSource="{Binding Source={StaticResource YourDataProvider}}"
   SelectedIndex="{Binding Path=YourValue, Mode=TwoWay, Converter={StaticResource SelectedToIndexConverter}, UpdateSourceTrigger=PropertyChanged}"/>

Удачи!:)

Ответ 5

Тип SelectedValuePath и SelectedValue должен быть ТОЧНО одинаковым.

Если, например, тип SelectedValuePath равен Int16, а тип свойства, который привязан к SelectedValue, равен int, он не будет работать.

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

Ответ 6

Развернувшись во что-то подобное, я просто подписался на событие SelectionChanged для раскрывающегося списка и установил с ним свое свойство данных. Глупый и жаль, что он не нужен, но он сработал.

Ответ 7

Можно ли установить SelectedValuePath = "Content" в combobox xaml, а затем использовать SelectedValue в качестве привязки?

Кажется, что у вас есть список строк и вы хотите, чтобы привязка просто привязывала строку к фактическому содержимому элемента в combobox, поэтому, если вы сообщите, какое свойство использовать для SelectedValue, оно должно работать; по крайней мере, это сработало для меня, когда я столкнулся с этой проблемой.

Кажется, что Content был бы разумным дефолтом для SelectedValue, но, возможно, это не так?

Ответ 8

Вы пытались создать событие, которое сигнализирует SelectName, например, OnPropertyChanged ( "SelectedName" )? Это сработало для меня.

Ответ 9

Режим привязки должен быть OneWayToSource или TwoWay, поскольку источник - это то, что вы хотите обновить. Режим OneWay является источником для цели и, следовательно, делает Source ReadOnly, что приводит к тому, что никогда не обновляется Источник.

Ответ 10

Ты знаешь... Я борюсь с этой проблемой часами сегодня, и ты знаешь, что я узнал? Это проблема DataType! Список, заполняющий ComboBox, был Int64, и я пытался сохранить значение в поле Int32! Ошибок не было, они просто не сохраняли значения!

Ответ 11

Просто решил это. Ха!!! Либо используйте [один из...].SelectedValue |.SelectedItem |.SelectedText Совет. Выбранное значение предпочтительнее для ComboStyle.DropDownList, а .SelectedText для ComboStyle.DropDown.

-Это должно решить вашу проблему. заняло у меня больше недели, чтобы решить эту маленькую фэн. ха!!