2014-10-05 85 views
1

我已經閱讀過其他文章,代替在代碼中指定DataContext,可以在XAML中指定它。在XAML中而不是在代碼後面設置DataContext

我有一個ObservableCollection和宣佈,以我的主類的構造函數填充,我還設置了DataContext的:

using System; 
using System.Windows; 
using System.Collections.ObjectModel; 

namespace ItemsControlDemo 
{ 
    public partial class MainWindow : Window 
    { 
     public ObservableCollection<Person> PersonList { get; set; } 

     public MainWindow() 
     { 
      InitializeComponent(); 

      PersonList = new ObservableCollection<Person>(); 

      PersonList.Add(new Person(16, "Abraham", "Lincoln")); 
      PersonList.Add(new Person(32, "Franklin", "Roosevelt")); 
      PersonList.Add(new Person(35, "John", "Kennedy")); 
      PersonList.Add(new Person(2, "John", "Adams")); 
      PersonList.Add(new Person(1, "George", "Washington")); 
      PersonList.Add(new Person(7, "Andrew", "Jackson")); 

      DataContext = this; 
     } 

     private void Button_Add_Click(object sender, RoutedEventArgs e) 
     { 
      PersonList.Add(new Person(3, "Thomas", "Jefferson")); 
     } 

     private void Button_Remove_Click(object sender, RoutedEventArgs e) 
     { 
      PersonList.Remove(TheDataGrid.SelectedItem as Person); 
     } 
    } 

    public class Person 
    { 
     public Person() { } 

     public Person(int id, string firstName, string lastName) 
     { 
      ID = id; 
      FirstName = firstName; 
      LastName = lastName; 
     } 

     public int ID { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
    } 
} 

如果我這樣做,在我的應用效果很好。

但是,如果我刪除「DataContext = this;」從構造函數中取而代之在我的應用程序的Window元素中設置DataContext

 DataContext="{Binding RelativeSource={RelativeSource Self}}" 

我得不到數據。

這是我設置DataContext的我從代碼中刪除它後,後面的XAML:

<Window x:Class="ItemsControlDemo.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:ItemsControlDemo" 
     Title="Items Control Demo" Height="350" Width="400" 
     WindowStartupLocation="CenterScreen" 
     DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*"/> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 
     <DataGrid Grid.Row="0" Name="TheDataGrid" SelectedValuePath="ID" 
        AutoGenerateColumns="False" 
        AlternatingRowBackground="Bisque" 
        ItemsSource="{Binding PersonList}"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Header="ID"   Binding="{Binding Path=ID}"/> 
       <DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}"/> 
       <DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}"/> 
      </DataGrid.Columns> 
     </DataGrid> 
     <StackPanel Grid.Row="1" Orientation="Horizontal" 
        HorizontalAlignment="Left" VerticalAlignment="Bottom"> 
      <Button Content="Add Item" Margin="5" Click="Button_Add_Click"/> 
      <Button Content="Remove Item" Margin="5" Click="Button_Remove_Click"/> 
     </StackPanel> 
    </Grid> 
</Window> 

在我在做什麼錯誤任何幫助將不勝感激。

謝謝!

+1

因爲您沒有在代碼隱藏文件中加載代碼而沒有遵循MVVM,您需要這樣做的任何原因? – Charleh 2014-10-05 19:59:43

+1

@Charleh:我知道我可以在後面的代碼中完成它,但這是一個示例應用程序,我正在使用它來了解有關使用DataGrid進行綁定的更多信息。因此,我正在探索所有可能的做法。 – PeterBuilt 2014-10-05 20:05:03

回答

2

你需要設置你的源之前調用的InitializeComponent

編輯:其實你只需要在InitializeComponent之前初始化它,因爲這是它實現INotifyCollectionChanged一個ObservableCollection,所以如果你修改集合,網格會更新了更改。

public MainWindow() 
    { 
     PersonList = new ObservableCollection<Person>(); 
     InitializeComponent(); 
     PersonList.Add(new Person(16, "Abraham", "Lincoln")); 
     PersonList.Add(new Person(32, "Franklin", "Roosevelt")); 
     PersonList.Add(new Person(35, "John", "Kennedy")); 
     PersonList.Add(new Person(2, "John", "Adams")); 
     PersonList.Add(new Person(1, "George", "Washington")); 
     PersonList.Add(new Person(7, "Andrew", "Jackson")); 
    } 
+0

謝謝!在填充數據源之前我沒有意識到我正在初始化。非常感謝您的及時答覆! – PeterBuilt 2014-10-05 20:14:05

+0

@PeterBuilt另外,你的Person類需要實現INotifyPropertyChanged – Tuco 2014-10-05 20:18:18

+0

因爲我使用ObservableCollection作爲Person對象列表,所以我不需要顯式實現NotifyPropertyChange。我相信這是使用ObservableCollection的優勢。 – PeterBuilt 2014-10-05 20:34:06

2

216的答案有效。或者,您可以實施INotifyPropertyChanged,以便在設置PersonList時通知XAML。

ObservableCollection只在收集變更項目時通知。如果您想在爲集合(例如PersonList = new ObservableCollection<Person>())分配新值時通知您,則需要執行INotifyPropertyChanged

public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private ObservableCollection<Person> personList; 

    public ObservableCollection<Person> PersonList 
    { 
     get { return personList; } 
     set 
     { 
      if (value == personList) 
       return; 
      personList = value; 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("PersonList")); 
     } 
    } 

    public MainWindow() 
    { 
     InitializeComponent(); 

     PersonList = new ObservableCollection<Person>(); 

     // etc. 
    } 
} 
+0

感謝您提供替代解決方案。 – PeterBuilt 2014-10-05 20:56:32

相關問題