ComboBox.SelectedValue não atualizar a partir da fonte de ligação
-
05-07-2019 - |
Pergunta
Aqui é o meu objeto de origem de ligação:
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
Aqui está o meu 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>
Aqui está o código-behind:
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
Quando a janela carrega pela primeira vez, as ligações ligar bem. O ComboBox contém os nomes de "Joe" e "Steve" e "Steve" é selecionado por padrão. No entanto, quando eu clicar em um botão para mudar o ObjectInstance para obj2, o ComboBox ItemsSource é preenchido corretamente na lista suspensa, mas o SelectedValue é definida como Nothing em vez de ser igual a obj2.SelectedName.
Solução
Nós tivemos um problema semelhante na semana passada. Tem a ver com a forma como SelectedValue
atualiza seus internos. O que encontramos foi se você conjunto SelectedValue
que não iria ver a mudança tivemos que SelectedItem
vez set que atualizar corretamente cada coisa. Minha conclusão é que SelectedValue
é projetado para get operações e não definir . Mas isso pode ser apenas um bug na versão atual do 3.5SP1 .net
Outras dicas
Para agitar uma conversa 2 anos de idade:
Outra possibilidade, se você está querendo usar cordas, é para vinculá-lo à propriedade de texto da caixa de combinação.
<ComboBox Text="{Binding Test}">
<ComboBoxItem Content="A" />
<ComboBoxItem Content="B" />
<ComboBoxItem Content="C" />
</ComboBox>
Isso é obrigado a algo como:
public class TestCode
{
private string _test;
public string Test
{
get { return _test; }
set
{
_test = value;
NotifyPropertyChanged(() => Test); // NotifyPropertyChanged("Test"); if not using Caliburn
}
}
}
O código acima é Two-Way por isso, se você definir Teste = "B"; em código, em seguida, a caixa de combinação mostrará 'B', e, em seguida, se você selecionar 'A' no menu suspenso, em seguida, a propriedade ligada irá refletir a alteração.
Use
UpdateSourceTrigger=PropertyChanged
na ligação
Problema:
As pesquisas de classe ComboBox para o objeto especificado usando o método IndexOf. Este método usa o método Equals para determinar a igualdade.
Solução:
Assim, tentar definir SelectedIndex usando SelectedValue via conversor assim:
C # código
//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}"/>
Boa sorte! :)
O tipo de SelectedValuePath
eo SelectedValue
deve ser exatamente o mesmo.
Se, por exemplo, o tipo de SelectedValuePath
é Int16
eo tipo da propriedade que se liga a SelectedValue
é int
não vai funcionar.
Eu gasto horas para encontrar isso, e é por isso que estou respondendo aqui depois de tanto tempo a pergunta foi feita. Talvez uma outra pobre rapaz como eu, com o mesmo problema pode vê-lo.
Ran em algo semelhante, finalmente, eu apenas subscrito para o evento SelectionChanged para a queda para baixo e definir a minha propriedade de dados com ele. Parva e gostaria que não era necessário, mas funcionou.
É razoável para definir o SelectedValuePath = "Content" em XAML do combobox e, em seguida, usar SelectedValue como a ligação?
Parece que você tem uma lista de strings e deseja a encadernação fazer apenas strings contra o conteúdo do item real no combobox, por isso, se você diga a ele que a propriedade para uso para o SelectedValue ele deve funcionar; pelo menos, que funcionou para mim quando eu corri através deste problema.
Parece conteúdo seria um padrão razoável para SelectedValue mas talvez não é?
Você tentou levantar um evento que sinais SelectName foi atualizado, por exemplo, OnPropertyChanged ( "SelectedName")? Que funcionou para mim.
No meu caso eu era vinculativa a uma lista enquanto eu deveria ser obrigatório para uma string.
O que eu estava fazendo:
private ObservableCollection<string> _SelectedPartyType;
public ObservableCollection<string> SelectedPartyType { get { return
_SelectedPartyType; } set {
_SelectedPartyType = value; OnPropertyChanged("SelectedPartyType"); } }
O que deve ser
private string _SelectedPartyType;
public string SelectedPartyType { get { return _SelectedPartyType; } set {
_SelectedPartyType = value; OnPropertyChanged("SelectedPartyType"); } }
O modo de ligação precisa ser OneWayToSource ou TwoWay desde que a fonte é o que você quer atualizado. Modo OneWay é origem para o destino e, portanto, faz com que o ReadOnly Fonte que resulta em não atualizar o código-fonte.
Você sabe ... Eu tenho lutado com este problema para horas de hoje, e você sabe o que eu descobri? Era uma questão DataType! A lista que foi preencher a caixa de combinação foi Int64, e eu estava tentando para armazenar o valor em um campo Int32! Nenhum erro foi sendo jogado, ele simplesmente não estava armazenando os valores!
Apenas resolvido isso. Hã!!! De qualquer utilização [um dos ...] .SelectedValue | .SelectedItem | .SelectedText Dica:. Valor selecionado é o preferido para ComboStyle.DropDownList enquanto .SelectedText é para ComboStyle.DropDown
-Este deve resolver o seu problema. Levei mais de uma semana para resolver este pequeno fyn. hah !!