これが私のバインディングソースオブジェクトです。
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はobj2.SelectedNameと等しくなる代わりにNothingに設定されます。
先週も同様の問題がありました。 SelectedValue
が内部を更新する方法に関係しています。私たちが見つけたのは、SelectedValue
を設定すると、代わりにSelectedItem
を設定する必要がある変更が表示されず、すべてが正しく更新されるということです。私の結論は、SelectedValue
はget用に設計された操作であり、設定されていないです。しかし、これは3.5sp1 .netの現在のバージョンのバグにすぎない可能性があります
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」を選択すると、バインドされたプロパティに変更が反映されます。
使用する
UpdateSourceTrigger=PropertyChanged
バインディングで
問題:
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}"/>
幸運を! :)
SelectedValuePath
とSelectedValue
の型は完全に同じでなければなりません。
たとえば、SelectedValuePath
のタイプがInt16
およびSelectedValue
にバインドするプロパティのタイプはint
であり、機能しません。
私はそれを見つけるのに何時間も費やします、そしてそれは私が質問が尋ねられた多くの時間の後にここで答えている理由です。同じ問題を抱えている私のような別の貧しい人がそれを見ることができるかもしれません。
同様のことを実行し、最後にドロップダウンのSelectionChangedイベントにサブスクライブし、それでデータプロパティを設定しました。愚かで、それが必要ではなかったが、うまくいったことを願う。
コンボボックスのxamlにSelectedValuePath = "Content"を設定し、SelectedValueをバインディングとして使用するのは妥当ですか?
文字列のリストがあり、コンボボックス内の実際のアイテムコンテンツに対して文字列のマッチングを行うようにバインドする必要があるようです。少なくとも、私がこの問題に出くわしたとき、それは私のために働いた。
ContentはSelectedValueの賢明なデフォルトのようですが、おそらくそうではないでしょうか?
SelectNameが更新されたことを通知するイベント、たとえばOnPropertyChanged( "SelectedName")を発生させましたか?それは私のために働いた。
私の場合、文字列にバインドする必要がありますが、リストにバインドしていました。
私がやっていたこと:
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"); } }
ご存知のように...私は今日この問題と何時間も戦い続けてきましたが、私が見つけたことを知っていますか?これはDataTypeの問題でした! ComboBoxに入力されたリストはInt64であり、Int32フィールドに値を保存しようとしていました!エラーはスローされず、値を保存していませんでした!
これを解決しました。えっ!!!どちらかを使用してください[...] .SelectedValue | .SelectedItem | .SelectedTextヒント:ComboStyle.DropDownListにはSelected Valueが推奨され、ComboStyle.DropDownには.SelectedTextが推奨されます。
-これで問題が解決するはずです。この小さなfynを解決するのに1週間以上かかりました。ハァッ!
ソースは更新する必要があるため、バインディングモードはOneWayToSourceまたはTwoWayである必要があります。モードOneWayはターゲットからソースへのソースであるため、ソースは読み取り専用になり、ソースは更新されません。