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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 19:44:37  来源:igfitidea点击:

ComboBox.SelectedValue not updating from binding source

wpfdata-bindingbindingcombobox

提问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 SelectedValueupdates its internals. What we found was if you set SelectedValueit would not see the change we had to instead set SelectedItemwhich would properly update every thing. My conclusion is that SelectedValueis 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 SelectedValuePathand the SelectedValuemust be EXACTLY the same.

theSelectedValuePath和 the的类型SelectedValue必须完全相同。

If for example the type of SelectedValuePathis Int16and the type of the property that binds to SelectedValueis intit will not work.

例如,如果SelectedValuePathisInt16的类型和绑定到SelectedValueis的属性的类型,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。哈!!