2011-06-09 63 views
2

我有一個複選框,一個簡單的組合框裏面是這樣:WPF的ItemsSource工作在代碼隱藏而不是在XAML

<ComboBox Height="23" HorizontalAlignment="Left" Margin="158,180,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" ItemsSource="{Binding collection}"> 
     <ComboBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <CheckBox Content="{Binding Name}"></CheckBox> 
       </StackPanel> 
      </DataTemplate> 
     </ComboBox.ItemTemplate> 
    </ComboBox> 

DataContext的僅僅是後面的代碼,並對其進行測試我使用下面的代碼:

public ObservableCollection<Foo> collection { get; set; } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     collection = new ObservableCollection<Foo>(); 
     this.comboBox1.ItemsSource = collection; 
     Foo f = new Foo("DSD"); 
     collection.Add(f); 
    } 

當我設置的ItemsSource爲我的代碼,然後它工作正常,但我想設置的ItemsSource在XAML,但它不使用XAML中上述工作。我也嘗試將其設置爲Path =「」。任何人都知道爲什麼?

謝謝

回答

3

您需要將DataContext分配給控件。是這樣的:

var window = new Window1(); 
window.DataContext = new WindowDC(); 
window.Show(); 

其中Window1類包含組合框,並WindowDC是這樣的:

public class WindowDC 
{ 
    public ObservableCollection<Foo> collection { get; set; } 
} 

這就是這將如何工作。

實際上,您將collection放入控件類中,並僅爲combobox設置datacontext。

但是,出於測試目的,您仍然可以在控制構造器中設置Combox.Datacontext。

2

WPF中的綁定總是有一個源。如果你沒有在綁定本身中指定源,那麼它將隱式地使用控件的DataContext或它的祖先。因此,如果要綁定到代碼隱藏文件中的屬性,則必須將DataContext設置爲包含collection屬性的類的對象。在你的情況下,這是窗口的實例(this)。

DataContext = this;

正如評論人員指出的那樣,它不被認爲是將商業邏輯或數據置於文件後面的代碼中的好樣式。因此,請考慮編寫一個單獨的類,其中包含您的collection屬性,您可以使用它來初始化DataContext。如果你正在寫更大的應用程序,你應該看看像MVVM這樣的模式,它使用數據綁定來提供視圖和模型之間更好的分離。

編輯:更改排序並納入反饋

+0

不要這樣做。這只是錯誤的,它打破了DataContext的整個概念,它用於將buisnesslogic與perpersentation分開。不,不。 – 2011-06-09 11:56:22

+1

我覺得給我一個這樣的倒退是不公平的。這個問題沒有任何相關的背景。他只想知道爲什麼他的樣本不起作用,我給了他缺失的鏈接。我們不在這裏討論架構的概念證明。這是一個例子,它不必解釋如何使用MVVM等。請考慮收回這個downvote。 – aKzenT 2011-06-09 12:42:24

+0

在任何情況下,我都將您的反饋併入原始答案並添加了評論。 – aKzenT 2011-06-09 12:54:09

0

確保您的代碼背後存在公共財產collection

後面的代碼中也做 this.DataContext = this

最後落實INotifyPropertyChanged告訴認爲你已經改變了收集,一旦你把它添加項目

public ObservableCollection<Foo> Collection 
{ 
get 
    { 
    return collection; 
    } 
set 
    { 
    collection = value; 
    OnPropertyChanged("Collection"); 

    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     collection = new ObservableCollection<Foo>(); 
     //this.comboBox1.ItemsSource = collection; 
     Foo f = new Foo("DSD"); 
     collection.Add(f); 
     OnPropertyChanged("Collection"); 
    } 
+0

INotifyPropertyChanged不是必需的。 DataContext在button_click()中未被更改 – 2011-06-09 12:02:21

0

當你設置組合的項目據工作源代碼在後面,因爲組合的來源正在像明智更新設置XAML中的項目源,你必須使用INotifyPropertyChanged做一個屬性,每當你通過這個屬性更新你的集合時不斷更新組合的itemsource。

private ObservableCollection<Foo> _Collection; 
public ObservableCollection<Foo> Collection 
{ 
get 
{ 
return collection; 
} 
set 
{ 
collection = value; 
OnPropertyChanged("Collection"); 
} 

現在,當您要填寫按鈕集合點擊你只需要設置集合中的財產..

_Collection = new ObservableCollection<Foo>(); 
Foo f = new Foo("DSD"); 
_Collection .Add(f); 
    Collection = _Collection ; //here property call OnPropertyChange 

喜歡聰明人,你可以提供數據給任何控制。它是INotifyPropertyChanged屬性的遊戲。 希望這會幫助你

相關問題