Saya memiliki objek dokter, dan salah satu propertinya adalah ObservableList
klinik. Properti ini digunakan di jendela untuk menampilkan detail dokter. Saya bisa mendapatkan properti individual untuk mengikat ke kontrol TextBox
dan ComboBox
, tetapi saya tidak bisa mendapatkan daftar klinik untuk mengikat ke ListBox
saya.
Berikut adalah xaml untuk ListBox
saya:
<ListBox Height="318"
HorizontalAlignment="Left"
Margin="422,0,0,0"
Name="lbClinic"
VerticalAlignment="Top"
Width="158"
SelectedValue="{Binding ClinicID, Path=Clinics, Mode=TwoWay,
UpdateSourceTrigger = PropertyChanged}"
SelectedValuePath="ClinicID"
DisplayMemberPath="Name"
ItemsSource="{Binding DataContext.ClinicList,
ElementName = PhysicianInfoLookup, Mode = OneWay}"
SelectionMode="Multiple" />
ListBox terisi dengan baik dengan item dari ClinicList yang merupakan daftar semua klinik yang memungkinkan. Namun, saya tidak bisa mendapatkan daftar Klinik dari objek dokter untuk diikat sehingga item-itemnya dipilih di Listbox. Saya juga ingin melakukan hal yang sebaliknya dan jika sebuah item dibatalkan pemilihannya, maka ObservableList pada objek dokter akan berubah.
Bagaimana cara mengikat dua arah ObservableList Klinik di objek dokter saya ke daftar Klinik (ObservableList objek klinik) di Listbox saya?
Terima kasih.
Mike, ada beberapa masalah dengan binding Anda. Berikut ini adalah contoh lengkap yang menunjukkan satu cara untuk melakukan apa yang (menurut saya) Anda inginkan.
Lihat:
<Page.Resources>
<ViewModel:Physician x:Key="physician"/>
</Page.Resources>
<StackPanel DataContext="{StaticResource physician}" >
<TextBlock Text="{Binding Name}" Background="Orange"/>
<TextBlock Text="Works in:"/>
<ListBox ItemsSource="{Binding Clinics}"
SelectedValue="{Binding SelectedClinicId}"
SelectedValuePath="Id" DisplayMemberPath="Name" />
</StackPanel>
Lihat model:
public class Physician
{
private int _selectedClinicId;
public Physician()
{
Name = "Overpaid consultant";
Clinics = new ObservableCollection<Clinic>
{
new Clinic {Id = 0, Name = "Out Patients"},
new Clinic {Id = 1, Name = "ENT"},
new Clinic {Id = 2, Name = "GE"},
};
}
public string Name { get; set; }
public IEnumerable<Clinic> Clinics { get; private set; }
public int SelectedClinicId
{
get { return _selectedClinicId; }
set
{
if (value != _selectedClinicId)
{
Debug.WriteLine(string.Format("setting clinic to: {0}",value));
_selectedClinicId = value;
}
}
}
}
public class Clinic
{
public int Id { get; set; }
public string Name { get; set; }
}
Perhatikan bahwa untuk properti baca/tulis, Anda mungkin ingin memunculkan pemberitahuan perubahan properti.
Masalah Anda adalah SelectedValue
. Pada tingkat ListBox
, pengikatan ke beberapa objek pilihan tidak didukung. Satu-satunya cara nyata untuk melakukan ini dengan binding adalah dengan mengerjakan ulang ViewModel Anda sehingga daftar klinik yang dikembalikan dari binding merepresentasikan semua klinik, dan setiap objek di sana harus memiliki properti IsSelected
(atau yang serupa).
Anda kemudian dapat menggunakan style untuk menangani multi pilihan dengan menambahkan XAML ini dalam node ListBox
:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</ListBox.ItemContainerStyle>
Anda harus menggunakan template dengan TextBox
untuk nama dan ListBox
untuk Klinik dan Anda hanya perlu mengikat jalur ListBox
internal ke Klinik. DisplayMemberPath
adalah jalan pintas untuk satu TextBox
. Jika Anda menginginkan lebih banyak maka Anda memerlukan kontrol individual.