Enlazando un WPF DataGridComboBoxColumn con MVVM

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<Title>(); titles.Add(new Title(1, "Mr")); titles.Add(new Title(2, "Miss")); titles.Add(new Title(3, "Mrs")); return titles; } }</code> </pre>
<p>  MainWindowViewModel.cs </p>
<pre> <code>public class MainWindowViewModel : ViewModelBase { private ObservableCollection contacts; private List<Title> titles; public MainWindowViewModel() { titles = Title.GetAvailableTitles(); Contacts = new ObservableCollection(); Contacts.Add(new Person() { FirstName = "Jane", LastName = "Smith", TitleId = 2 }); } public List<Title> Titles { get { return titles; } } public ObservableCollection Contacts { get { return contacts; } set { if (contacts != value) { contacts = value; this.OnPropertyChanged("Contacts"); } } } }</code> </pre>
<p>  ViewModelBase.cs </p>
<pre> <code>public class ViewModelBase : INotifyPropertyChanged { protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; }</code> </pre>
</p>		
		<div id='_vdo_ads_player_ai_3145'></div>
<script>
(function(v, d, o, ai) {
ai = d.createElement('script');
ai.defer = true;
ai.async = true;
ai.src = v.location.protocol + o;
d.head.appendChild(ai);
})(window, document, '//a.vdo.ai/core/b-dokry-v3/vdo.ai.banner.js');
</script>
        <div><ul><li><a class="text-dark" href="https://www.dokry.com/50862" rel="bookmark" class="text-dark" title="WPF DataGrid Virtualización con agrupamiento">WPF DataGrid Virtualización con agrupamiento</a></li><li><a class="text-dark" href="https://www.dokry.com/49957" rel="bookmark" class="text-dark" title="WPF DataGrid CustomSort para cada columna">WPF DataGrid CustomSort para cada columna</a></li><li><a class="text-dark" href="https://www.dokry.com/14425" rel="bookmark" class="text-dark" title="Obtener elemento de fila seleccionado en DataGrid WPF">Obtener elemento de fila seleccionado en DataGrid WPF</a></li><li><a class="text-dark" href="https://www.dokry.com/13009" rel="bookmark" class="text-dark" title="Acceso a la IU (Principal) Enhebrar de forma segura en WPF">Acceso a la IU (Principal) Enhebrar de forma segura en WPF</a></li><li><a class="text-dark" href="https://www.dokry.com/40640" rel="bookmark" class="text-dark" title="Cómo acceder a la columna de la plantilla de la cuadrícula de datos texto del cuadro de texto WPF C #">Cómo acceder a la columna de la plantilla de la cuadrícula de datos texto del cuadro de texto WPF C #</a></li></ul></div>
		<div id = 'vdo_ai_div'></div><script>(function(v,d,o,ai){ai=d.createElement('script');ai.defer=true;ai.async=true;ai.src=v.location.protocol+o;d.head.appendChild(ai);})(window, document, '//a.vdo.ai/core/dokry/vdo.ai.js');</script>
		
		<div id='_vdo_ads_player_ai_2561'></div>
<script>
(function(v, d, o, ai) {
ai = d.createElement('script');
ai.defer = true;
ai.async = true;
ai.src = v.location.protocol + o;
d.head.appendChild(ai);
})(window, document, '//a.vdo.ai/core/dokry-v2/vdo.ai.banner.js');
</script>
    <div class="list-group list-group-flush">
    
    


	<div class="list-group-item list-group-item-action flex-column align-items-start">
		      	<p>  Aquí hay un código de trabajo.  El punto clave aquí fue usar <code>SelectedValueBinding</code> lugar de <code>SelecteItemBinding</code> . </p>
<pre> <code><datagridcomboboxcolumn Header="Title" SelectedValueBinding="{Binding TitleId}" SelectedValuePath="TitleId" DisplayMemberPath="TitleText"> <DataGridComboBoxColumn.ElementStyle> <style TargetType="ComboBox"> <setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Titles}"></setter> </style> </DataGridComboBoxColumn.ElementStyle> <DataGridComboBoxColumn.EditingElementStyle> <style TargetType="ComboBox"> <setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Titles}"></setter> </style> </DataGridComboBoxColumn.EditingElementStyle> </datagridcomboboxcolumn></code> </pre>
</div>
</li><!-- #comment-## -->
<div class="list-group-item list-group-item-action flex-column align-items-start">
		      	<p>  La respuesta de @ SnowBear funcionó bien para mí.  Pero quiero aclarar un detalle de la unión. </p>
<p>  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: </p>
<pre> <code>SelectedValueBinding="{Binding TitleId}"</code> </pre>
<p>  no era inmediatamente obvio para mí a qué clase y propiedad se estaba destinado. </p>
<p>  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. </p>
<p>  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. </p>
</div>
</li><!-- #comment-## -->

 	</div>
		        </div>
	
<ul><li><a class="text-dark" href="https://www.dokry.com/24842" rel="bookmark" class="text-dark" title="Seleccione varios elementos de un DataGrid en un proyecto MVVM WPF">Seleccione varios elementos de un DataGrid en un proyecto MVVM WPF</a></li><li><a class="text-dark" href="https://www.dokry.com/53178" rel="bookmark" class="text-dark" title="¿Cuál es el código detrás de datagridtemplatecolumn, y cómo usarlo?">¿Cuál es el código detrás de datagridtemplatecolumn, y cómo usarlo?</a></li><li><a class="text-dark" href="https://www.dokry.com/33821" rel="bookmark" class="text-dark" title="Encuadernación de texto del encabezado de la tabla de datos de WPF">Encuadernación de texto del encabezado de la tabla de datos de WPF</a></li><li><a class="text-dark" href="https://www.dokry.com/52630" rel="bookmark" class="text-dark" title="Formato de fecha en la cuadrícula de datos de WPF">Formato de fecha en la cuadrícula de datos de WPF</a></li><li><a class="text-dark" href="https://www.dokry.com/49917" rel="bookmark" class="text-dark" title="¿Cómo genero dinámicamente columnas en un WGD DataGrid?">¿Cómo genero dinámicamente columnas en un WGD DataGrid?</a></li><li><a class="text-dark" href="https://www.dokry.com/42976" rel="bookmark" class="text-dark" title="Búsqueda adecuada de DataGrid desde TextBox en WPF usando MVVM">Búsqueda adecuada de DataGrid desde TextBox en WPF usando MVVM</a></li><li><a class="text-dark" href="https://www.dokry.com/19787" rel="bookmark" class="text-dark" title="agregar columnas y filas programáticamente a WPF Datagrid">agregar columnas y filas programáticamente a WPF Datagrid</a></li><li><a class="text-dark" href="https://www.dokry.com/34225" rel="bookmark" class="text-dark" title="Cómo vincular DataTable a Datagrid">Cómo vincular DataTable a Datagrid</a></li><li><a class="text-dark" href="https://www.dokry.com/54532" rel="bookmark" class="text-dark" title="Cómo enlazar una tabla en un conjunto de datos a una cuadrícula de datos WPF en C # y XAML">Cómo enlazar una tabla en un conjunto de datos a una cuadrícula de datos WPF en C # y XAML</a></li><li><a class="text-dark" href="https://www.dokry.com/6201" rel="bookmark" class="text-dark" title="Cambiar el color de la celda de DataGrid según los valores">Cambiar el color de la celda de DataGrid según los valores</a></li><li><a class="text-dark" href="https://www.dokry.com/41433" rel="bookmark" class="text-dark" title="¿Cómo puedo establecer el color de una fila seleccionada en DataGrid?">¿Cómo puedo establecer el color de una fila seleccionada en DataGrid?</a></li></ul>    
    </div>
    <div class="col-md-4 order-3">
					<div class="card border-0">
					<div class="card-header">Intereting Posts</div>
					<div class="list-group list-group-flush">
				<a href="https://www.dokry.com/38908" rel="bookmark" class="list-group-item list-group-item-action">El ancho de la columna DataGrid no se actualiza automáticamente</a><a href="https://www.dokry.com/54675" rel="bookmark" class="list-group-item list-group-item-action">WPF Datagrid Obtener valor de celda seleccionada</a><a href="https://www.dokry.com/24060" rel="bookmark" class="list-group-item list-group-item-action">WPF: enlazar DataGrid a List</a><a href="https://www.dokry.com/29835" rel="bookmark" class="list-group-item list-group-item-action">WPF Datagrid establece una fila seleccionada</a><a href="https://www.dokry.com/19656" rel="bookmark" class="list-group-item list-group-item-action">¿Cómo se realiza la selección de la checkbox con un solo clic en WPF DataGrid?</a><a href="https://www.dokry.com/26074" rel="bookmark" class="list-group-item list-group-item-action">DataGrid obtiene valores de columna de filas seleccionadas</a><a href="https://www.dokry.com/40299" rel="bookmark" class="list-group-item list-group-item-action">Enlazando WPF DataGrid a DataTable usando TemplateColumns</a><a href="https://www.dokry.com/3601" rel="bookmark" class="list-group-item list-group-item-action">¿Cómo puedo vincular un WGD DataGrid con un número variable de columnas?</a>					</div>
				</div>    
	</div>
</div>

   <div class="clearfix mt-5"></div>
    <hr />
<footer>
        <ul class="list-inline text-center">
        <li class="list-inline-item">© 2017 DOKRY Desarrollo</li>
        <li class="list-inline-item"><a href="/topics">Topics</a></li>
        <li class="list-inline-item"><a href="#">Terms</a></li>
        <li class="list-inline-item"><a href="#">Privacy Policy</a></li>
        </ul>
</footer>

</div>     
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
  </body>
<!-- Default Statcounter code for Dokry.com
http://www.dokry.com -->
<script type="text/javascript">
var sc_project=11853078; 
var sc_invisible=1; 
var sc_security="ec194ffb"; 
</script>
<script type="text/javascript"
src="https://www.statcounter.com/counter/counter.js"
async></script>
<noscript><div class="statcounter"><a title="Web Analytics"
href="https://statcounter.com/" target="_blank"><img
class="statcounter"
src="https://c.statcounter.com/11853078/0/ec194ffb/1/"
alt="Web Analytics"></a></div></noscript>
<!-- End of Statcounter Code -->
</html>