He visto las respuestas a variousquestions, pero no he logrado asignar el contenido en las respuestas al problema que estoy tratando de resolver. Lo he reducido al siguiente código (representativo del resultado que estoy tratando de lograr), y básicamente quiero poder representar el Person.TitleId
como su correspondiente Title.TitleText
cuando la fila no está siendo editada, y tengo la caída -down bound correctamente para que muestre el TitleText
s en el menú desplegable y escribe el TitleId
asociado de nuevo en el registro Person
cuando se modificó.Enlazando un WGT DataGridComboBoxColumn con MVVM
En resumen, ¿qué pongo en mi <DataGridComboBoxColumn>
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
<Grid>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=Contacts}">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Title" SelectedItemBinding="{Binding Person}">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Titles}"/>
<Setter Property="IsReadOnly" Value="True"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Titles}"/>
<Setter Property="DisplayMemberPath" Value="TitleText" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
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<Title> GetAvailableTitles()
{
var titles = new List<Title>();
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<Person> contacts;
private List<Title> titles;
public MainWindowViewModel()
{
titles = Title.GetAvailableTitles();
Contacts = new ObservableCollection<Person>();
Contacts.Add(new Person() { FirstName = "Jane", LastName = "Smith", TitleId = 2 });
}
public List<Title> Titles
{
get { return titles; }
}
public ObservableCollection<Person> 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;
}
Ayudaría si pudiera delinear qué partes de ese 'plan' no funcionan/cuáles realmente funcionan. p.ej. ¿puede ubicar la lista de ItemsSource de ComboBox? –
También: Desde el aspecto de cómo se usa 'Title', la clase parece redundante y sería mejor que fuera reemplazada por un' Dictionary '. –
@ H.B. - A medida que el código permanece, la cuadrícula no muestra la representación textual del valor inicial (es decir, el TitleText apropiado para Person.TitleId), el menú desplegable se llena con {Mr, Mrs, Miss} correctamente y seleccionando un elemento en el resultados desplegables en TestMVVM.Models.Título que se muestra en la cuadrícula (TestMVVM.Models es el espacio de nombres en la solución, que eliminé por brevedad). – Rob