29

这是我的绑定源对象:

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。

4

12 回答 12

37

上周我们遇到了类似的问题。它与如何SelectedValue更新其内部结构有关。我们发现,如果你设置SelectedValue它不会看到我们必须设置的更改,而是SelectedItem会正确更新所有内容。我的结论是,它SelectedValue为 get操作而设计的,而不是 set。但这可能只是当前版本 3.5sp1 .net 中的一个错误

于 2008-10-29T16:31:07.890 回答
17

挑起 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”,则绑定属性将反映更改。

于 2010-07-21T16:03:49.113 回答
10

采用

UpdateSourceTrigger=PropertyChanged 

在绑定中

于 2012-05-10T07:10:40.683 回答
6

问题:

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

祝你好运!:)

于 2011-05-13T03:02:50.460 回答
5

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

例如,如果SelectedValuePathisInt16的类型和绑定到SelectedValueis的属性的类型int将不起作用。

我花了几个小时来找到它,这就是为什么我在问了这么多时间之后在这里回答这个问题。也许像我这样有同样问题的可怜人可以看到它。

于 2011-04-21T10:26:15.017 回答
3

遇到类似的事情,最后我只是订阅了下拉菜单的 SelectionChanged 事件并用它设置我的数据属性。愚蠢并希望不需要它,但它确实有效。

于 2009-08-06T20:42:06.643 回答
2

SelectedValuePath="Content"在组合框的xaml中设置,然后SelectedValue用作绑定是否合理?

看来您有一个字符串列表,并且希望绑定仅针对组合框中的实际项目内容进行字符串匹配,因此如果您告诉它使用哪个属性,SelectedValue它应该可以工作;至少,当我遇到这个问题时,这对我有用。

看起来 Content 似乎是一个明智的默认设置,SelectedValue但也许不是?

于 2009-08-11T20:38:23.817 回答
1

您是否尝试过引发一个表明 SelectName 已更新的事件,例如 OnPropertyChanged("SelectedName")?这对我有用。

于 2012-02-06T20:56:04.847 回答
1

在我的情况下,我绑定到一个列表,而我应该绑定到一个字符串。

我在做什么:

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"); } }
于 2019-04-09T11:11:42.050 回答
0

绑定模式需要是 OneWayToSource 或 TwoWay,因为源是您想要更新的。模式 OneWay 是 Source to Target,因此使 Source ReadOnly 导致永远不会更新 Source。

于 2010-03-09T00:34:57.227 回答
0

你知道...我今天已经与这个问题斗争了几个小时,你知道我发现了什么吗?这是一个数据类型问题!填充 ComboBox 的列表是 Int64,我试图将值存储在 Int32 字段中!没有抛出错误,只是没有存储值!

于 2010-03-23T20:54:41.910 回答
0

刚刚解决了这个。啊!!!要么使用 [one of...] .SelectedValue | .SelectedItem | .SelectedText 提示:ComboStyle.DropDownList 首选 Selected Value,而 ComboStyle.DropDown 首选 .SelectedText。

- 这应该可以解决您的问题。我花了一个多星期来解决这个小问题。哈哈!!

于 2015-12-14T18:51:26.517 回答