2010-12-14 52 views
1

我有一個汽車類是這樣的:爲什麼數據綁定不起作用?

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

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

我也有一個用戶控件:

public partial class CarListItem : UserControl 
{ 
    private Car car; 

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

} 

使用XAML:

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

但數據綁定不起作用。我究竟做錯了什麼?

我想在userControl上顯示汽車的名稱。

+0

你是否確實在任何地方設置了名字? – 2010-12-14 18:10:54

+0

當我創建一輛汽車時,我設置了名稱 – eflles 2010-12-14 21:32:04

回答

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。

+0

糟糕的做法從代碼中設置UserControl的'DataContext'(如果我在 2010-12-14 18:19:26

+2

@Dan:嗨,夥計,這傢伙(OP)需要先了解基本知識。他必須學會討論甚至考慮最佳實踐。 – decyclone 2010-12-14 18:23:50

+0

@丹不同意,在你的答案上貼出解釋 – 2010-12-14 19:50:03

0

您的綁定綁定到datacontext的car.Name。在你的情況下,DataContext是NULL。

您有幾種選擇:

  1. 設置爲CarListItem實例
  2. 數據上下文指定綁定源。

第一個選項通常更好。

更妙的想法是定義一個DataTemplateCar,並使用Car s,而不是明確的CarListItem個清單:

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

現在,你可以使用這個模板列表ItemTemplate

+0

@downvoter:解釋是受歡迎的。 – Vlad 2010-12-14 18:21:00

+0

以這種方式使用控件的'DataContext'是脆弱的,很容易被破壞。您應該在控件的模板中隱藏更深層次的內容或使用替代方法。我的回答表明一個更強大的解決方案(另外,我在投票之前投了票。) – 2010-12-14 18:27:33

+0

如果你問我,不值得贊成+1 – 2010-12-14 18:51:53

1

對於綁定工作,您需要在Control的DataContext屬性中具有值。它也可以被繼承。因此,子控件如果沒有子控件,也可以訪問父母的DataContext

除非與Self Binding一起使用,否則屬性(甚至不公開)不會幫助您進行綁定。

爲了讓你的代碼工作,

更換

this.car = car; 

隨着

this.DataContext = car; 

和替換

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

隨着

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

嘿,Down投票是什麼?有問題? – decyclone 2010-12-14 18:22:24

+0

以這種方式使用控件的'DataContext'是脆弱的,容易被破壞。您應該在控件的模板中隱藏更深層次的內容或使用替代方法。我的回答表明一個更強大的解決方案 – 2010-12-14 18:27:55

+0

如果你問我,不值得贊同+1 – 2010-12-14 18:52:25

-1

使用this.DataContext工作,但它是脆弱的,可怕的,而不是來設計應用程序的好方法。如果我要消耗你的用戶控制和寫此XAML:

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

...那麼你的控制將打破,無論Car屬性是否設置正確與否。這不是很漂亮。

更強大的方法是將Xaml中的UserControl元素標記爲x:Name,並在綁定中使用ElementName。所以,你的控制看起來是這樣的:

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

現在,如果你想設置的Grid(使用DataContext="{Binding Car, ElementName=control}"DataContext,你可以得到的datacontext的利益更可靠的方法。

但是,對於這些工作,您需要將您的car字段暴露爲屬性,而不僅僅是字段。您還需要實現INotifyPropertyChanged,以便UI在您更改屬性值時實現,但您可以通過在構造函數中調用InitializeComponent()之前設置car來臨時解決此問題。

+2

現在,我不明白你從哪裏得到'UserControl'標記。問題中的「XAML」是UserControl的一部分。我感謝您對代碼健壯性的擔憂,但是您的代碼只是明顯地混淆和誤導。使用屬性來暴露控件的數據顯然是錯誤的做法。你應該總是使用'Model'來公開綁定數據。但是,這不是重點。這個人對DataContext和公共屬性感到困惑,而不是最佳實踐。 – decyclone 2010-12-14 18:38:35

+0

''UserControl'標籤是用戶控件的xaml中的標準根元素(它可能是問題中引用的'Grid'的父元素)。我很欣賞你在說什麼(如果我有更多時間可以讓我的答案更詳細),但我不同意教壞習慣。我會回答那些建議使用datacontext解決這些問題的方法,就像大多數人會對任何不好的練習(如導致儘可能多的問題的全局變量等)的其他答案一樣。 – 2010-12-14 19:02:28

+1

我也很困惑你的例子。你是說當我創建用戶控件時,最好的做法是命名頂級元素,並在控件中使用該名稱而不是數據上下文作爲綁定源?這就是你所說的話,我不但沒有這樣做,我從來沒有見過任何人這樣做。所以爲什麼? – 2010-12-14 19:33:33