2009-04-01 10 views
9

Digamos que tengo un tipo de datos a medida que se ve algo como esto:propiedades complejo de unión en Silverlight/WPF

public class MyDataType 
{ 
    public string SimpleProp1; 
    public string SimpleProp2; 
    public List<SomeType> ComplexProp; 
} 

ahora hava un control enlazado de datos (es decir ItemsControl o cuadrícula de datos), que se crea de forma dinámica. ¿Cómo se vería el enlace definido en el código xaml para acceder a una subpropiedad de la propiedad compleja? Pensé que debería ser algo como esto:

<TextBox Text="{Binding simpleSubProp, path=ComplexProp[0]}" /> 

o

<TextBox Text="{Binding path=ComplexProp[0].simpleSubProp}" /> 

pero ambos de los que me dan errores de análisis XML. ¿Cómo debería verse correctamente? ¿Es posible referirse a un artículo específico de una propiedad de colección de una manera? Si no es así, ¿qué otras opciones tengo?

de edición, el escenario no parece ser lo suficientemente claro:

tengo una

IEnumberable<MyDataType> 

que está obligado a ItemsControl, dentro de la DataTemplate tengo varios cuadros de texto que necesitan para referirse a subpropiedades de un objeto en la Lista de la propiedad compleja.

Respuesta

7

Parece que los indexadores de rutas de acceso se rompen en Silverlight Indexers in property paths are broken. La forma de evitarlo es como se sugiere en la publicación y utilizar un IValueConverter.

XAML

<UserControl x:Class="Silverlight.Mine.Page" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sys="System" 
    xmlns:sm="clr-namespace:Silverlight.Mine;assembly=Silverlight.Mine" 
    Width="400" Height="300"> 
    <UserControl.Resources> 
     <sm:SomeTypeConverter x:Key="MySomeTypeConverter" /> 
    </UserControl.Resources>  
    <Grid x:Name="LayoutRoot" Background="White"> 
     <TextBlock x:Name="myTextBlock" Text="{Binding Path=SomeDates, Converter={StaticResource MySomeTypeConverter}}" /> 
    </Grid> 
</UserControl> 

C# Page.xaml.cs

namespace Silverlight.Mine 
{ 
    public partial class Page : UserControl 
    { 
     private SomeType m_mySomeType = new SomeType(); 

     public Page() 
     { 
      InitializeComponent(); 
      myTextBlock.DataContext = m_mySomeType; 
     } 
    } 
} 

C# SomeType.cs

namespace Silverlight.Mine 
{ 
    public class SomeType 
    { 
     public List<DateTime> SomeDates { get; set; } 

     public SomeType() 
     { 
      SomeDates = new List<DateTime>(); 
      SomeDates.Add(DateTime.Now.AddDays(-1)); 
      SomeDates.Add(DateTime.Now); 
      SomeDates.Add(DateTime.Now.AddDays(1)); 
     } 
    } 

    public class SomeTypeConverter : IValueConverter 
    { 
     public object Convert(object value, 
         Type targetType, 
         object parameter, 
         CultureInfo culture) 
     { 
      if (value != null) 
      { 
       List<DateTime> myList = (List<DateTime>)value; 
       return myList[0].ToString("dd MMM yyyy"); 
      } 
      else 
      { 
       return String.Empty; 
      } 
     } 

     public object ConvertBack(object value, 
           Type targetType, 
           object parameter, 
           CultureInfo culture) 
     { 
      if (value != null) 
      { 
       return (List<DateTime>)value; 
      } 
      return null; 
     } 
    } 
} 
+0

¡Voy a intentarlo, gracias! – gsnerf

1

No estoy seguro de que pueda hacer eso. Normalmente vinculará una lista a algo así como un cuadro de lista (u otro control "repetitivo") y luego cada elemento dentro podrá enlazar al elemento relevante en la lista.

+0

Puede que no lo haya aclarado lo suficiente, tengo un IEnumerable vinculado a un ItemsControl. Dentro de DataTemplate de mis ItemsControl necesito hacer referencia a la subpropiedad de un elemento específico en la propiedad compleja. – gsnerf

2

Prueba {Enlazando ComplexProp (0) .simpleSubProp}. Si eso no funciona, puede escribir un convertidor simple para hacer esto también.

+0

Thx por su respuesta, desafortunadamente esto me da una System.ArgumentException "Ruta de enlace inválida; carácter". ¿Cómo sería un convertidor para esto? Pensé que los convertidores se usarían normalmente para formatear datos de una manera específica – gsnerf

1

De acuerdo con la Path Syntax on MSDN, sólo puede hacer:

<TextBox Text="{Binding ComplexProp[0].simpleSubProp}" /> 

puede ser el "path =" minúscula que dio errores? Pruebe con "Path =". Además, no estoy seguro si esto funciona en Silverlight ...

+0

Esa página es para WPF, no para Silverlight. Silverlight no admite propiedades indexadas en el enlace. – mattmanser

+0

El título de la pregunta dice "Silverlight/WPF". –

+0

¡El método de indexación parece funcionar solo en algunos casos en Silverlight, sin embargo! – gsnerf

4

hago este tipo de cosas todo el tiempo, hay dos maneras Me gustaría abordar este problema dependiendo de lo que quieras de él.

Si realmente desea el único miembro específico de la lista, puede usar un convertidor.El XAML sería algo como esto:

<TextBox Text="{Binding MyDataTypeInstance, Converter={StatacResources SpecificInstanceConverter}}" /> 

Eso no es por lo general lo que necesito sin embargo, por lo general necesito uno de control para visualizar la totalidad del objeto comlex, si ese es el caso, la forma de hacerlo es más como los siguientes:

<StackPanel> 
    <Textblock Text="{Binding SimpleProp1}"/> 
    <TextBlock Text="{Bidning SimpleProp2}"/> 
    <ItemsControl ItemsSource="{Binding ComplexProp}> 
      <ItemsControl.ItemsTemplate> 
       <DataTemplate> 
        <StackPanel> 
         <TextBlock Text="{Binding ComplexPropertyName}/> 
         <InputToolkit:NumericUpDown Value="{Binding ComplexPropertyValue}/> 
        </StackPanel> 
       </DataTemplate> 
      </ItemsControl.ItemsTemplate> 
    </ItemsControl> 
</StackPanel> 

me gusta este método porque mi GUI coincide con mis objetos de negocio, y como resultado, por lo general termina mucho más limpio que si estoy comprobación de índices específicos de código subyacente.

1

Para generalizar todo esto, le sugiero que use un convertidor de valor como lo mencionaron otros, y use la opción ConverterParam para pasar un índice.

2

Esto ahora funciona bien en Silverlight 4.

Una cosa a tener en cuenta, la clase tiene tres campos públicos. Cámbialos a Propiedades (y sería una idea implementar INotifyPropertyChanged también) y luego el siguiente código funciona.

<StackPanel> 
    <TextBlock Text="{Binding Path=SimpleProp1}" /> 
    <TextBox Text="{Binding Path=ComplexProp[0].SimpleSubProp, Mode=TwoWay}" Width="200" Height="60"/> 
</StackPanel> 

casos también es importante ya que los enlaces entre mayúsculas y minúsculas.