2009-04-01 9 views
9

私は次のようになりますカスタムデータ型を持っているとしましょう:結合複合体の特性

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

今私は、データバインドコントロール(すなわち、ItemsControlにまたはデータグリッドを)HAVA、それが動的に作成されます。 xamlコードで定義されたバインディングは、複合プロパティのサブプロパティにどのようにアクセスするように見えますか?私はそれがこのようになるはずと思った:

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

または

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

が、それらの両方が私にXML解析エラーを与える

。どのように正しく見えるのでしょうか?それは、コレクションのプロパティの特定の項目を参照することも可能ですか?そうでない場合は、他にどのようなオプションがありますか?

EDIT、シナリオは十分に明確ではないようです。

を私はを参照する必要がある複数のTextBoxを持っているのDataTemplate内、のItemsControlにバインドされている

IEnumberable<MyDataType> 

を持っています複合プロパティのList内のオブジェクトのサブプロパティ。

答えて

7

popertyパスインデクサーのように見えますが、シルバーライトIndexers in property paths are brokenで壊れています。それを回避する方法は、投稿に示唆されているように、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

私はそれを試してみましょう、thx! – gsnerf

1

私はあなたがそれを行うことができるとは確信していません。通常はリストをリストボックス(または別の「反復」コントロール)のようなものにバインドし、その中の各項目はリストの関連要素にバインドできます。

+0

私は十分に明確にしていないかもしれませんが、IEnumerable がItemsControlにバインドされています。私のItemsControlのDataTemplateの中で、私は複合プロパティの特定の項目のサブプロパティを参照する必要があります。 – gsnerf

2

{Binding ComplexProp(0).simpleSubProp}を試してください。それでも問題が解決しない場合は、これを行う簡単なConverterを作成することもできます。

+0

あなたの答えは、残念ながら、これは私にSystem.ArgumentException "無効なバインディングパス;文字"を与えます。 このコンバータの外観はどうですか?私はコンバータが特定の方法でデータを形式化するために通常使用されると思った。 – gsnerf

1

Path Syntax on MSDNによると、あなただけ行うことができます。

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

それはあなたのエラーを与えた小文字の「パス=」であってもよいですか? "Path ="を試してください。また、Silverlightでこれが動作するかどうかはわかりません。

+0

そのページはSilverlightではなくWPF用です。 Silverlightはバインディングでインデックス付きのプロパティをサポートしていません。 – mattmanser

+0

質問のタイトルに「Silverlight/WPF」と表示されています。 –

+0

インデックス作成方法はSilverlightのいくつかのケースでしか機能しないようですが、それでもやはり! – gsnerf

4

私はこの種のものにすべての時間を行う、2つの方法があります私はあなたがそれから欲しいものに応じてこの問題にアプローチします。

本当にリストの特定のメンバーだけが必要な場合は、コンバータを使用できます。その場合は、次のようにそれを行うための方法は、より多くのようなものです、通常、私は全体comlexオブジェクトを表示するには、一つの制御を必要とし、私も必要なものは通常はありません

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

:XAMLは次のようになります。

<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> 

私のGUIが私のビジネスオブジェクトに一致し、その結果として、それは通常、私はコードビハインドで特定のインデックスをチェックしていた場合よりもクリーンたくさん終わるので、私はこの方法が好きです。

1

これを一般化するには、他の人が触れたようにバリューコンバータを使用し、ConverterParamオプションを使用してインデックスを渡すことをお勧めします。

2

これは今クラスには、3つのパブリックフィールドがあり、

一つのことに注意するのSilverlight 4で[OK]を動作します。それらをPropertiesに変更してください(INotifyPropertyChangedを実装するアイデアとなります)。そして、次のコードが動作します。

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

大文字と小文字が区別されるため、大文字と小文字も重要です。