Miré las respuestas a varias preguntas , pero no logré asignar el contenido de las respuestas al problema que bash resolver. Lo he reducido al siguiente código (representativo del resultado que estoy tratando de lograr), y básicamente quiero poder Person.TitleId
el Person.TitleId
como su Title.TitleText
correspondiente cuando la fila no está siendo editada, y tiene el menú desplegable enlazado correctamente para que muestre el texto del TitleText
en el menú desplegable y escriba el TitleId
asociado de nuevo en el registro de la Person
cuando se TitleId
.
En resumen, ¿qué pongo en mi para lograr esto?
App.xaml.cs
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var viewModel = new ViewModels.MainWindowViewModel(); var mainWindow = new MainWindow(); mainWindow.DataContext = viewModel; mainWindow.ShowDialog(); }
MainWindow.xaml
Person.cs
public class Person { public int TitleId { get; set; } public string LastName { get; set; } public string FirstName { get; set; } }
Title.cs
public struct Title { public Title(int titleId, string titleText) : this() { TitleId = titleId; TitleText = titleText; } public string TitleText { get; private set; } public int TitleId { get; private set; } public static List GetAvailableTitles() { var titles = new List(); titles.Add(new Title(1, "Mr")); titles.Add(new Title(2, "Miss")); titles.Add(new Title(3, "Mrs")); return titles; } }
MainWindowViewModel.cs
public class MainWindowViewModel : ViewModelBase { private ObservableCollection contacts; private List titles; public MainWindowViewModel() { titles = Title.GetAvailableTitles(); Contacts = new ObservableCollection(); Contacts.Add(new Person() { FirstName = "Jane", LastName = "Smith", TitleId = 2 }); } public List Titles { get { return titles; } } public ObservableCollection Contacts { get { return contacts; } set { if (contacts != value) { contacts = value; this.OnPropertyChanged("Contacts"); } } } }
ViewModelBase.cs
public class ViewModelBase : INotifyPropertyChanged { protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; }
Aquí hay un código de trabajo. El punto clave aquí fue usar SelectedValueBinding
lugar de SelecteItemBinding
.
La respuesta de @ SnowBear funcionó bien para mí. Pero quiero aclarar un detalle de la unión.
En el ejemplo de @ Rob, las clases de Título y Persona usan TitleID. Por lo tanto, en la respuesta de @ SnowBear, en el enlace:
SelectedValueBinding="{Binding TitleId}"
no era inmediatamente obvio para mí a qué clase y propiedad se estaba destinado.
Como el atributo SelectedValueBinding apareció en DataGridComboBoxColumn, es vinculante para ItemsSource del DataGrid que lo contiene. En este caso, la colección Contactos de objetos Persona.
En mi caso, la colección DataSource de DataGrid fue atribuida con una propiedad que fue nombrada diferente de ValuePath de la colección ItemSource de ComboBox. Por lo tanto, mi valor de SelectedValueBinding estaba ligado a una propiedad diferente a la propiedad nombrada en SelectedValuePath de ComboBox.