2010-12-14 17 views
1

私はこのような車のクラスを持っている:データバインディングが機能しないのはなぜですか?

public class car 
{ 
    public String Name {get; private set;} 

    public car(string name) 
    { 
     this.Name = name; 
    } 
} 

私はまた、ユーザーコントロールがあります:XAMLで

public partial class CarListItem : UserControl 
{ 
    private Car car; 

    public CarListItem (Car car) 
    { 
     InitializeComponent(); 
     this.car= car; 
    } 

} 

<Grid> 
    <Label Content="{Binding Path=car.Name}" Name="lblCarName"/> 
</Grid> 

が、データバインディングが動作しませんが。私は間違って何をしていますか?

私はuserControlに車の名前を表示したいと思います。

+0

実際にどこにでも名前を設定していますか? –

+0

私は車を作るときに名前を設定します – eflles

答えて

2

あなたは車でバインディング式を前書きする必要はありません...

<Grid> 
    <Label Content="{Binding Name}" Name="lblCarName"/> 
</Grid> 

...加えて、あなたのUserControl

public partial class CarListItem : UserControl 
{ 
    public CarListItem (Car car) 
    { 
     InitializeComponent(); 

     this.DataContext = car; 
    } 
} 

DataContextを設定する必要があります。また、私の仮定がされそれ以外の場合は、空の文字列またはnull以外の車のctorに名前を渡していることを示します。

+0

コードから 'UserControl'の' DataContext'を設定するのは悪い習慣です(xamlの '

+2

@ダン:ちょっとおい、この男(OP)はまず基本的な理解が必要です。彼は議論し、ベストプラクティスを検討するのに十分なことを学ばなければならない。 – decyclone

+0

@ダンは同意しない、答えに投稿した説明 –

0

あなたのバインディングは、datacontextのcar.Nameにバインドされます。あなたの場合、DataContextはNULLです。

あなたは、いくつかのオプションがあります:

  1. CarListItemインスタンス
  2. にデータコンテキストを設定するにはバインディングソースを指定します。

通常、最初のオプションが優れています。

さらに良いアイデアがあなたのCarためDataTemplateを定義し、代わりに明示的なCarListItem秒のCarのリストを使用することです:

<DataTemplate DataType="{x:Type local:Car}"> 
    <Grid> 
     <Label Content="{Binding Path=Name}"/> 
    </Grid> 
</DataTemplate> 

さて、あなたは、リスト内のItemTemplateとしてこのテンプレートを使用することができます。

+0

@downvoter:説明を歓迎します。 – Vlad

+0

このようにコントロールの 'DataContext'を使うことは壊れやすく、簡単に壊れます。これをコントロールのテンプレートでもっと隠すか、代替を使用する必要があります。私の答えはより強固な解決策を示唆しています。 (また、私はあなたの編集の前に投票しました) –

+0

あなたが私に尋ねると、downvoteの価値はありません+1 –

1

バインディングを使用するには、ControlのDataContextプロパティに値を設定する必要があります。それは継承することもできます。したがって、子コントロールは親のDataContextにアクセスできません。

Self Bindingと一緒に使用しない限り、プロパティ(公開されていなくても)はバインドに役立ちません。

this.DataContext = car; 

this.car = car; 

を交換し、

<Label Content="{Binding Path=car.Name}" Name="lblCarName"/> 

を交換し、あなたのコードを動作させるために

<Label Content="{Binding Path=Name}" Name="lblCarName"/> 
+0

ねえ、下の投票とは何ですか?何か問題でも? – decyclone

+0

このようにコントロールの 'DataContext'を使うことは壊れやすく、簡単に壊れます。これをコントロールのテンプレートでもっと隠すか、代替を使用する必要があります。私の答えはより強固な解決策を示唆しています。 –

+0

あなたが私に尋ねると、downvoteの価値はありません+1 –

-1

this.DataContextます作業を使用して、それはあなたのアプリケーションを設計するための良い方法壊れやすいと恐ろしいとはありません。私はあなたのユーザーコントロールを消費し、このXAMLを記述した場合:

<CarListItem DataContext="{Binding MyThing}" /> 

...その後、あなたの制御にかかわらずCarプロパティが正しく設定されているかどうかの、切断されます。それほど美しいものではありません。

より堅牢なアプローチは、x:NameでXamlのUserControl要素をマークし、バインドにElementNameを使用することです。だから、あなたのコントロールは、このようなものになります。あなたはGrid(使用DataContext="{Binding Car, ElementName=control}")にDataContextを設定したい場合は、今すぐ

<UserControl x:Name="control" ....... (namespaces/etc here)> 
    <Grid> 
    <Label Content="{Binding Car.Name, ElementName=control}" Name="lblCarName"/> 
    </Grid> 

を、あなたは、より堅牢な方法でのDataContextの利益を得ることができます。

ただし、これが機能するには、フィールドとしてではなく、carフィールドをプロパティとして公開する必要があります。また、carの前に設定することで、プロパティの値を変更するときにUIが実現するように、INotifyPropertyChangedを実装する必要があります。InitializeComponent()をコンストラクタに呼び出します。

+2

今、私はあなたがその 'UserControl'タグをどこから得たのか分かりません。問題の 'XAML'はUserControlの一部です。コードの堅牢性に関する懸念に感謝しますが、あなたのコードは単純に混乱して誤解を招くだけです。コントロールからデータを公開するためにプロパティを使用するのは間違った方法です。バインディングのためにデータを公開するには、常に 'Model'を使うべきです。しかし、ここではその点は重要ではありません。その人はベストプラクティスではなく、 'DataContext'やpublicプロパティと混同されている。 – decyclone

+0

'

+1

私はあなたの事例でも本当に混乱しています。ユーザーコントロールを作成するとき、最上位の要素に名前を付け、コントロール内でバインディングソースとしてデータコンテキストではなくその名前を使用することをお勧めしますか?それはあなたが言っているようだ、私は決してそれをやったことがない、私は誰もそれを行うことを見たことがない。なぜ? –

関連する問題