Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding complex properties in Silverlight/WPF

Lets say I have a custom data type that looks something like this:

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

now I hava a data bound control (i.e. ItemsControl or DataGrid), that is created dynamically. How would the binding defined in xaml code look like to acces a subproperty of the complex property? I thought it should look something like this:

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

or

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

but both of those give me xml parse errors. How should it look correctly? Is it even possible to refer to a specific item of a collection property in souch a way? If it is not, what other options do I have?

EDIT, The scenario doesn't seem to be clear enough:

I have an

IEnumberable<MyDataType>

that is bound to an ItemsControl, inside the DataTemplate I have multiple TextBoxes that need to refer to subproperties of an object in the List of the complex property.

like image 378
gsnerf Avatar asked Apr 01 '09 07:04

gsnerf


1 Answers

Looks like poperty path indexers are broken in Silverlight Indexers in property paths are broken. The way to get around it is as suggested in the post and to use an 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;
        }
    }
}
like image 147
sipsorcery Avatar answered Oct 15 '22 20:10

sipsorcery