wpf ComboBox.SelectedValue 未从绑定源更新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/247413/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ComboBox.SelectedValue not updating from binding source
提问by Rob Sobers
Here's my binding source object:
这是我的绑定源对象:
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
Here is my XAML:
这是我的 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>
Here's the code-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
When the Window first loads, the bindings hook up fine. The ComboBox contains the names "Joe" and "Steve" and "Steve" is selected by default. However, when I click a button to switch the ObjectInstance to obj2, the ComboBox ItemsSource gets populated correctly in the dropdown, but the SelectedValue is set to Nothing instead of being equal to obj2.SelectedName.
当窗口第一次加载时,绑定很好地连接起来。ComboBox 包含名称“Joe”和“Steve”,默认情况下选择“Steve”。但是,当我单击一个按钮将 ObjectInstance 切换到 obj2 时,ComboBox ItemsSource 在下拉列表中被正确填充,但 SelectedValue 设置为 Nothing 而不是等于 obj2.SelectedName。
回答by Aaron Fischer
We had a similar issue last week. It has to do with how SelectedValue
updates its internals. What we found was if you set SelectedValue
it would not see the change we had to instead set SelectedItem
which would properly update every thing. My conclusion is that SelectedValue
is designed for getoperations and not set. But this may just be a bug in the current version of 3.5sp1 .net
上周我们遇到了类似的问题。它与如何SelectedValue
更新其内部结构有关。我们发现如果你设置SelectedValue
它不会看到我们必须设置的更改,而是SelectedItem
正确更新每件事。我的结论是它SelectedValue
是为 get操作而不是 set 设计的。但这可能只是 3.5sp1 .net 当前版本中的一个错误
回答by ASeale
To stir up a 2 year old conversation:
挑起一个 2 年前的对话:
Another possibility, if you're wanting to use strings, is to bind it to the Text property of the combobox.
如果您想使用字符串,另一种可能性是将其绑定到组合框的 Text 属性。
<ComboBox Text="{Binding Test}">
<ComboBoxItem Content="A" />
<ComboBoxItem Content="B" />
<ComboBoxItem Content="C" />
</ComboBox>
That's bound to something like:
那一定是这样的:
public class TestCode
{
private string _test;
public string Test
{
get { return _test; }
set
{
_test = value;
NotifyPropertyChanged(() => Test); // NotifyPropertyChanged("Test"); if not using Caliburn
}
}
}
The above code is Two-Way so if you set Test="B"; in code then the combobox will show 'B', and then if you select 'A' from the drop down then the bound property will reflect the change.
上面的代码是双向的,所以如果你设置 Test="B"; 在代码中,组合框将显示“B”,然后如果您从下拉列表中选择“A”,则绑定属性将反映更改。
回答by Junier
Use
用
UpdateSourceTrigger=PropertyChanged
in the binding
在绑定中
回答by Pavel Kovalev
Problem:
问题:
The ComboBox class searches for the specified object by using the IndexOf method. This method uses the Equals method to determine equality.
ComboBox 类使用 IndexOf 方法搜索指定的对象。此方法使用 Equals 方法来确定相等性。
Solution:
解决方案:
So, try to set SelectedIndex using SelectedValue via Converter like this:
因此,尝试通过 Converter 使用 SelectedValue 设置 SelectedIndex,如下所示:
C# code
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
xml
<ComboBox
ItemsSource="{Binding Source={StaticResource YourDataProvider}}"
SelectedIndex="{Binding Path=YourValue, Mode=TwoWay, Converter={StaticResource SelectedToIndexConverter}, UpdateSourceTrigger=PropertyChanged}"/>
Good luck! :)
祝你好运!:)
回答by Dummy01
The type of the SelectedValuePath
and the SelectedValue
must be EXACTLY the same.
theSelectedValuePath
和 the的类型SelectedValue
必须完全相同。
If for example the type of SelectedValuePath
is Int16
and the type of the property that binds to SelectedValue
is int
it will not work.
例如,如果SelectedValuePath
isInt16
的类型和绑定到SelectedValue
is的属性的类型,int
它将不起作用。
I spend hours to find that, and that's why I am answering here after so much time the question was asked. Maybe another poor guy like me with the same problem can see it.
我花了好几个小时才找到这个问题,这就是为什么我在问了这么多时间之后才在这里回答的原因。也许另一个像我一样有同样问题的可怜人可以看到它。
回答by Dummy01
Ran into something similar, finally I just subscribed to the SelectionChanged event for the drop down and set my data property with it. Silly and wish it was not needed, but it worked.
遇到了类似的情况,最后我只是订阅了下拉列表的 SelectionChanged 事件,并用它设置了我的数据属性。愚蠢并希望它不需要,但它起作用了。
回答by Mikeb
Is it reasonable to set the SelectedValuePath="Content" in the combobox's xaml, and then use SelectedValue as the binding?
在combobox的xaml中设置SelectedValuePath="Content",然后使用SelectedValue作为绑定是否合理?
It appears that you have a list of strings and want the binding to just do string matching against the actual item content in the combobox, so if you tell it which property to use for the SelectedValue it should work; at least, that worked for me when I ran across this problem.
看起来您有一个字符串列表,并且希望绑定只对组合框中的实际项目内容进行字符串匹配,因此如果您告诉它要为 SelectedValue 使用哪个属性,它应该可以工作;至少,当我遇到这个问题时,这对我有用。
It seems like Content would be a sensible default for SelectedValue but perhaps it isn't?
似乎 Content 是 SelectedValue 的合理默认值,但也许不是?
回答by davidinjc
Have you tried raising an event that signals SelectName has been updated, e.g., OnPropertyChanged("SelectedName")? That worked for me.
您是否尝试过引发一个表明 SelectName 已更新的事件,例如 OnPropertyChanged("SelectedName")?那对我有用。
回答by Rajon Tanducar
In my case I was binding to a list while I should be binding to a string.
在我的情况下,我绑定到一个列表,而我应该绑定到一个字符串。
What I was doing:
我在做什么:
private ObservableCollection<string> _SelectedPartyType;
public ObservableCollection<string> SelectedPartyType { get { return
_SelectedPartyType; } set {
_SelectedPartyType = value; OnPropertyChanged("SelectedPartyType"); } }
What should be
应该是什么
private string _SelectedPartyType;
public string SelectedPartyType { get { return _SelectedPartyType; } set {
_SelectedPartyType = value; OnPropertyChanged("SelectedPartyType"); } }
回答by Sam Darteh
Just resolved this. Huh!!! Either use [one of...] .SelectedValue | .SelectedItem | .SelectedText Tip: Selected Value is preferred for ComboStyle.DropDownList while .SelectedText is for ComboStyle.DropDown.
刚刚解决了这个问题。哼!!!要么使用 [one of...] .SelectedValue | .SelectedItem | .SelectedText 提示:Selected Value 是 ComboStyle.DropDownList 的首选,而 .SelectedText 是 ComboStyle.DropDown 的首选。
-This should solve your problem. took me more than a week to resolve this small fyn. hah!!
- 这应该可以解决您的问题。我花了一个多星期才解决这个小fyn。哈!!