Detalle maestro: Cómo obtener un control desde una plantilla dentro del ContentControl “detalle”.
Tengo un ListView (en el lado ‘maestro’) cuya selección controla la propiedad Content de un ContentControl (en el lado ‘detalle’). El árbol visual del ContentControl viene de dos recursos DataTemplate que utilizan DataType para elegir qué vista de detalle renderizar en función de lo que se selecciona en el ListView. Esa parte funciona bien.
La parte con la que estoy luchando es que hay un control en particular dentro de las plantillas al que necesito hacer referencia cada vez que cambia (por ejemplo, cambia la plantilla seleccionada o cambia la selección del ListView de modo que se recrea la instancia del control).
En el controlador de eventos ListView.SelectionChanged, encuentro que el ContentControl aún no se ha actualizado con su nuevo árbol visual, por lo que inicialmente está vacío en la primera selección, y para las selecciones posteriores su árbol visual coincide con la selección anterior en lugar de la nueva.
He intentado retrasar mi código programándolo en el Dispatcher con una prioridad tan baja como DispatcherPriority.Loaded, lo cual funciona para la primera selección, pero en selecciones posteriores mi código aún se ejecuta antes de que se actualice el árbol visual.
¿Existe un evento mejor al que debería estar conectado para ejecutarse cada vez que se cambia el árbol visual del ContentControl para reflejar un valor de contenido cambiado vinculado a su propiedad Content?
Información adicional: la razón por la que necesito acceder a la plantilla DataTemplate expandida es que necesito establecer de manera efectiva la propiedad IList SelectedItems de mi modelo de vista en la propiedad SelectedItems de un control DataGrid. Dado que DataGrid.SelectedItems no es una propiedad de dependencia, tengo que hacer esto manualmente en el código.
davy.ai
La clase
ContentControl
proporciona un evento llamadoContentChanged
que se activa cuando cambia la propiedadContent
. Puedes suscribirte a este evento para ejecutar código cada vez que elContentControl
actualice su árbol visual para reflejar un cambio en su propiedadContent
. En tu caso, puedes añadir un controlador de eventos a este evento que identifique el control específico dentro delDataTemplate
seleccionado al que necesitas hacer referencia y guarde una referencia a él en un campo o propiedad de tu modelo de vista. De esta manera, cada vez que se actualice el árbol visual, podrás acceder a la referencia del control desde tu modelo de vista y realizar las operaciones necesarias en él.Código de ejemplo:
“`csharp
public class MiViewModel
{
private DataGrid _selectedGrid;
}
public static class VisualTreeUtilities(DependencyObject parent) where TChild : DependencyObject (child);
{
// Método de utilidad para encontrar un control secundario de un tipo dado en un árbol visual
public static TChild FindChild
{
var childCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is TChild typedChild)
{
return typedChild;
}
else
{
var nestedResult = FindChild
if (nestedResult != null)
{
return nestedResult;
}
}
}
return null;
}
}
“`