Zone de liste déroulante.SelectedValue non mise à jour à partir d'une source contraignante

Voici mon objet de source de liaison:

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

Voici mon 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>

voici le code-derrière:

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

lorsque la fenêtre se charge pour la première fois, les fixations se raccordent très bien. Le ComboBox contient les noms "Joe" et "Steve" et "Steve" est sélectionné par défaut. Cependant, quand je clique sur un bouton pour passer L'ObjectInstance à obj2, le ComboBox ItemsSource est rempli correctement dans la liste déroulante, mais la valeur Selectedteded est définie à rien au lieu de être égal à obj2.SelectedName.

24
demandé sur Litisqe Kumar 2008-10-29 19:11:34

11 réponses

Nous avons eu un problème similaire la semaine dernière. Il a à voir avec la façon dont SelectedValue actualise ses internes. Ce que nous avons trouvé était si vous mettez SelectedValue il ne serait pas voir le changement, nous avons dû les remplacer par SelectedItem qui mettrait à jour chaque chose correctement. Ma conclusion est que SelectedValueconçu pour obtenir de l' opérations et set. Mais il se peut que ce ne soit qu'un bug dans la version actuelle de 3.5sp1. net

31
répondu Aaron Fischer 2012-02-08 17:16:21

Pour remuer jusqu'à 2 ans de la conversation:

une autre possibilité, si vous voulez utiliser des chaînes, est de les lier à la propriété Text du combobox.

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

C'est lié à quelque chose comme:

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

le code ci-dessus est bidirectionnel donc si vous définissez Test="B"; dans le code alors le combobox affichera 'B', et puis si vous sélectionnez 'A' à partir de la goutte vers le bas alors la propriété liée reflétera le changement.

12
répondu ASeale 2010-07-21 16:03:49

Utiliser

UpdateSourceTrigger=PropertyChanged 

dans la liaison

7
répondu Junier 2012-05-10 14:35:01

Problème:

la classe ComboBox recherche l'objet spécifié en utilisant la méthode IndexOf. Cette méthode utilise la méthode des égaux pour déterminer l'égalité.

Solution:

alors, essayez de définir SelectedIndex en utilisant SelectedValue via convertisseur comme ceci:

C # code

//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}"/>

Bonne chance! :)

6
répondu Pavel Kovalev 2013-05-03 16:22:52

le type de SelectedValuePath et SelectedValue doit être EXACTEMENT le même.

Si, par exemple, le type de SelectedValuePathInt16 et le type de la propriété qui se lie à SelectedValueint ça ne marchera pas.

je passe des heures à trouver cela, et c'est pourquoi je réponds ici après tant de temps la question a été posée. Peut-être qu'un pauvre type comme moi avec le même problème peut le voir.

5
répondu Dummy01 2011-04-21 10:26:15

J'ai rencontré quelque chose de similaire, finalement je viens de m'abonner à L'événement SelectionChanged pour le drop down et de définir ma propriété de données avec elle. C'est idiot et j'aimerais que ça ne soit pas nécessaire, mais ça a marché.

3
répondu 2009-08-06 20:42:06

Est-il raisonnable de fixer le SelectedValuePath="Contenu" dans la zone de liste déroulante du xaml, et ensuite utiliser SelectedValue que la liaison?

il semble que vous ayez une liste de chaînes et que vous voulez que la liaison fasse juste la correspondance des chaînes avec le contenu réel de l'article dans le combobox, donc si vous lui dites quelle propriété utiliser pour la valeur sélectionnée il devrait fonctionner; au moins, cela a fonctionné pour moi quand je suis tombé sur ce problème.

Il semble que le Contenu serait une valeur par défaut raisonnable pour SelectedValue mais peut-être n'est-ce pas?

2
répondu Mikeb 2009-08-11 20:38:23

avez-vous essayé de soulever un événement qui signale que SelectName a été mis à jour, par exemple, OnPropertyChanged("SelectedName")? Ce qui a fonctionné pour moi.

1
répondu davidinjc 2012-02-06 20:56:04

le Mode de reliure doit être OneWayToSource ou TwoWay puisque la source est ce que vous voulez mettre à jour. Mode OneWay est Source à cible et rend donc la Source en lecture seule, ce qui a pour résultat de ne jamais mettre à jour la Source.

0
répondu Chuck Borcher 2010-03-09 00:34:57

Vous savez... Je me bats avec ce problème depuis des heures aujourd'hui, et tu sais ce que j'ai découvert? C'était un problème de type de données! La liste qui peuplait le ComboBox était Int64, et j'essayais de stocker la valeur dans un champ Int32! Il n'y avait pas d'erreur, il ne stockait pas les valeurs!

0
répondu VBRocks 2010-03-23 20:54:41

Simplement résolu le problème. Hein!!! Soit utiliser [l'un des...] .SelectedValue/.SelectedItem/.SelectedText Astuce: la valeur sélectionnée est préférée pour ComboStyle.DropDownList while .SelectedText est pour ComboStyle.déroulante.

-Cela devrait résoudre votre problème. m'a fallu plus d'une semaine pour résoudre ce petit fyn. ah!!

0
répondu Sam Darteh 2015-12-14 18:51:26