ComboBox.SelectedValue 未从绑定源更新
Posted
技术标签:
【中文标题】ComboBox.SelectedValue 未从绑定源更新【英文标题】:ComboBox.SelectedValue not updating from binding source 【发布时间】:2010-09-19 19:56:54 【问题描述】:这是我的绑定源对象:
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。
【问题讨论】:
【参考方案1】:上周我们遇到了类似的问题。它与SelectedValue
如何更新其内部结构有关。我们发现,如果您设置SelectedValue
,它不会看到我们必须设置的更改,而是设置SelectedItem
,这将正确更新所有内容。我的结论是SelectedValue
专为获取操作而设计,未设置。但这可能只是当前版本 3.5sp1 .net 中的一个错误
【讨论】:
确认 .NET 4 中仍然存在此问题...最好仅依靠SelectedItem
而不是 SelectedValue
我目前在 .NET 4.5 中遇到了 SelectedValue
的问题...对我来说 SelectedItem
也解决了这个问题。
我有一个类似的问题,这似乎与你描述的相反,我只使用 SelectedItem ***.com/questions/22300281/…
这个答案解决了这个问题(SelectedItem
实际上做了这两个家伙似乎认为SelectedValue
应该做的事情),但它对问题的原因有误。问题是SelectedValue
needs SelectedValuePath
. This is documented。 SelectedValue
和 SelectedItem
做不同的事情。
我设法通过将UpdateSourceTrigger=PropertyChanged
添加到SelectedValue
绑定来解决这个问题。对我来说,我不得不设定这个值,这感觉像是一种特殊的荒谬。【参考方案2】:
挑起 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";在代码中,组合框将显示“B”,然后如果您从下拉列表中选择“A”,则绑定属性将反映更改。
【讨论】:
【参考方案3】:使用
UpdateSourceTrigger=PropertyChanged
在绑定中
【讨论】:
Mode=TwoWay
和 UpdateSourceTrigger=PropertyChanged 必须明确设置。不要混淆它们的默认值。
并不总是有效,例如在绑定类的属性时。当您更改属性时,值不会更新【参考方案4】:
问题:
ComboBox 类使用 IndexOf 方法搜索指定的对象。此方法使用 Equals 方法来确定相等性。
解决方案:
所以,尝试通过 Converter 使用 SelectedValue 设置 SelectedIndex,如下所示:
C# 代码
//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
,它将不起作用。
我花了几个小时才找到它,这就是为什么我在问了这么多时间之后在这里回答这个问题。也许像我这样有同样问题的可怜人可以看到它。
【讨论】:
是的,还有一个像你一样的可怜人。还有Int16
vs int
我的问题。【参考方案6】:
遇到了类似的情况,最后我只是订阅了下拉菜单的 SelectionChanged 事件并用它设置我的数据属性。愚蠢,希望它不需要,但它有效。
【讨论】:
【参考方案7】:在combobox的xaml中设置SelectedValuePath="Content"
,然后使用SelectedValue
作为绑定是否合理?
您似乎有一个字符串列表,并且希望绑定仅针对组合框中的实际项目内容进行字符串匹配,因此,如果您告诉它要为SelectedValue
使用哪个属性,它应该可以工作;至少,当我遇到这个问题时,这对我有用。
对于SelectedValue
,内容似乎是合理的默认设置,但也许不是?
【讨论】:
感谢您为我指明了正确的方向。我想要 ComboBoxItem 的 Name 属性,所以我设置了 SelectedValuePath="Name",它就像一个冠军【参考方案8】:您是否尝试过引发表明 SelectName 已更新的事件,例如 OnPropertyChanged("SelectedName")?这对我有用。
【讨论】:
【参考方案9】:在我的情况下,我绑定到一个列表,而我应该绑定到一个字符串。
我在做什么:
private ObservableCollection<string> _SelectedPartyType;
public ObservableCollection<string> SelectedPartyType get return
_SelectedPartyType; set
_SelectedPartyType = value; OnPropertyChanged("SelectedPartyType");
应该是什么
private string _SelectedPartyType;
public string SelectedPartyType get return _SelectedPartyType; set
_SelectedPartyType = value; OnPropertyChanged("SelectedPartyType");
【讨论】:
【参考方案10】:绑定模式需要为 OneWayToSource 或 TwoWay,因为源是您要更新的内容。模式 OneWay 是 Source to Target,因此使 Source ReadOnly 导致永远不会更新 Source。
【讨论】:
【参考方案11】:你知道...我今天已经为这个问题争论了几个小时,你知道我发现了什么吗?这是一个数据类型问题!填充 ComboBox 的列表是 Int64,我试图将值存储在 Int32 字段中!没有抛出任何错误,只是没有存储值!
【讨论】:
【参考方案12】:刚刚解决了这个问题。啊!!! 要么使用 [one of...] .SelectedValue | .SelectedItem | .SelectedText 提示:ComboStyle.DropDownList 首选 Selected Value,而 ComboStyle.DropDown 首选 .SelectedText。
-这应该可以解决您的问题。我花了一个多星期来解决这个小问题。哈哈!!
【讨论】:
请使用其中一个,而不是两个或全部 3 个以上是关于ComboBox.SelectedValue 未从绑定源更新的主要内容,如果未能解决你的问题,请参考以下文章
MVVM WPF ComboBox SelectedValue 不是确切值
WinForm ComboBox SelectedValue 属性与 SelectedIndex