2014-10-05 84 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

相关问题