2010-06-10 3 views
6

Este ejemplo es ciertamente un poco artificial, pero estoy haciendo algo similar. Digamos que tengo las siguientes clases simples:¿Existe una manera simple de especificar un enlace de datos WPF donde la ruta tiene un "nivel" alto?

public class Person 
{ 
    public string Name { get; set; } 
    public List<Alias> Aliases { get; set; } 
} 

public class Alias 
{ 
    public string AliasName { get; set; } 
} 

Y vamos a decir que no tengo Xaml con una rejilla LayoutRoot, y una cuadrícula de datos en la que desee acceder a la propiedad Name dentro de la cuadrícula de datos lugar de las propiedades Alias ​​como en la segunda columna aquí:

<Grid x:Name="LayoutRoot" DataContext="PersonInstance"> 
    <DataGrid ItemsSource="{Binding Aliases}"> 
     <DataGrid.Columns> 
      <data:DataGridTextColumn Header="AliasName" Binding="{Binding AliasName, Mode=TwoWay}"/> 
      <data:DataGridTextColumn Header="Name" Binding="{Binding ../Name, Mode=TwoWay}"/> 
     </DataGrid.Columns> 
    </DataGrid> 
</Grid> 

eso es intuitivamente cómo iba a tratar de unir el nombre, pero no hace falta decir que se parece estúpida. ¿Hay algo así cuando se especifica una ruta, o se ve obligado a obtener una fuente relativa hasta el contexto de datos de LayoutRoot. Si es necesario, ¿cuál es la forma más eficiente?

+0

¿Por qué no funciona? 'Binding =" {Binding Name, Mode = TwoWay} "' – Amsakanna

+0

@Veer, porque no hay propiedad Name en la clase Alias ​​... – Anvaka

+0

@Anvaka: Pero el contexto de datos se establece como la instancia de la clase de persona. Debe saber la propiedad Nombre. – Amsakanna

Respuesta

10

Esto debería funcionar para usted:

<DataGridTextColumn Header="Name" 
        Binding="{Binding RelativeSource={RelativeSource 
                 FindAncestor, 
                 AncestorLevel=3, 
                 AncestorType={x:Type Grid}, 
                 Mode=FindAncestor}, 
                Path=DataContext.Name}"/> 

Puede utilizar cualquiera de los siguientes:

Para hacer que el elemento de origen es igual a la de los padres más cercano de un tipo dado:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type 
desiredType}}} 

Para hacer que el elemento fuente sea igual al enésimo padre más cercano de un tipo dado:

{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorLevel=n, AncestorType={x:Type desiredType}}} 

Para hacer que el elemento de origen es igual al anterior elemento de datos en una colección enlazado a datos:

{Binding RelativeSource={RelativeSource PreviousData}} 
+1

Esto es escandalosamente detallado. Su primer ejemplo debe escribirse '{Binding RelativeSource = {RelativeSource FindAncestor, Grid, 3}}'. Los demás deberían simplificarse también. Cualquiera que entienda la función FindAncestor entenderá 'FindAncestor, Grid, 3' tan fácilmente como sus cuatro líneas de código, y con menos pensamiento. –

0

creo que no hay mejor manera de hacer esto que el uso de la fuente con respecto al árbol. Puede volver a escribir su modelo (por ejemplo, agregue una referencia al padre Person desde Alias), pero ese no es el mejor enfoque.

Desde el rendimiento prospectivo, nunca encontré cuellos de botella en enlaces de fuente relativos. Siempre hay algo más que mantiene tu aplicación lejos de la velocidad del cohete.

Cuestiones relacionadas