将WPF DataGrid绑定到List

时间:2014-04-21 17:10:54

标签: c# wpf xaml mvvm datagrid

我知道之前已经问了好几次,但我无法弄清楚我在这里犯了什么(基本的)错误。

我有一个提供标签窗口的程序。特定类型的选项卡的数量是动态定义的,所以我创建了一个继承自Tab的UserControl(NTab),这样我只需要将另一个NTab附加(或移除)到TabControl,我们就可以开展业务。

现在,每个NTab都有一个DataGrid,用户输入一些X-Y坐标。我的想法是创建一个具有X和Y属性的NPoint类以及一个可以绑定到DataGrid的List。为此,我编写了以下代码。

我知道这会将Points(我ICollectionView的{​​{1}}绑定到.xaml末尾的List<NPoint>,但是当我运行时程序我得到一个“空”网格,如下所示。显然有一个DataGrid,但显然没有显示任何数据。

Window with empty grid, not even showing rows or columns

我将代码与here中的代码进行了比较,关于.xaml中的DataGrid,代码隐藏和数据元素的定义(在我的案例中,NPoint,在教程的情况下,消费者) ),但是没有看到我的错误,因为它在教程中不起作用。有什么想法吗?

nPoint个

DataGrid

NTab.xaml

public class NPoint : INotifyPropertyChanged
{
    double _X;
    double _Y;
    public event PropertyChangedEventHandler PropertyChanged;
    public double X 
    { 
        get { return _X; }
        set
        {
            _X = value;
            EmitPropertyChanged("X");
        }
    }
    public double Y
    { 
        get { return _Y; }
        set
        {
            _Y = value;
            EmitPropertyChanged("Y");
        }
    }
    void EmitPropertyChanged(string property)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
    public NPoint(double x, double y)
    {
        _X = x;
        _Y = y;
    }
}

NTab.xaml.cs

<UserControl x:Class="WPF.NTab"
         x:Name="ThisTab"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:charting="clr-namespace:System.Windows.Forms.DataVisualization.Charting;assembly=System.Windows.Forms.DataVisualization"
         xmlns:local="clr-namespace:WPF"
         mc:Ignorable="d" >
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
    </Grid.RowDefinitions>
    <!-- ... -->
    <Grid Grid.Row="1" Grid.Column="0">
        <!-- ... -->
    </Grid>
    <Grid Grid.Row="2">
        <!-- ... -->
    </Grid>
    <Grid Grid.Row="3">
        <!-- ... -->
    </Grid>
    <DataGrid Grid.Row="4"
              ItemsSource="{Binding Points, ElementName=ThisTab}" 
              AutoGenerateColumns="True" />
</Grid>
</UserControl>

1 个答案:

答案 0 :(得分:1)

DataGrid不显示数据,因为绑定不起作用。我们来看看你现有的绑定:

<DataGrid Grid.Row="4" ItemsSource="{Binding Points}" />

绑定尝试访问NTab的DataContext的points属性。无论NTab的DataContext是什么,它似乎都不是你的重点列表。

您应该能够通过 Points 属性将DataContext设置为NTab实例来解决问题:

public NTab()
{
    ...
    Points = CollectionViewSource.GetDefaultView(_Points);
    DataContext = this;
}

或(最好)在XAML中按元素名称进行绑定:

<UserControl x:Class="WPF.NTab" x:Name="thisNTab" ...>
    ...
    <DataGrid Grid.Row="4" ItemsSource="{Binding Points, ElementName=thisNTab}" />
</UserControl>

仅此一项还不能为您提供结果,因为如果 Points 属性发生更改,绑定将无法识别。实现 INotifyPropertyChanged 机制,或将 Points 转换为DependencyProperty。下面是使用只读DependencyProperty的代码:

private static readonly DependencyPropertyKey PointsPropertyKey =
    DependencyProperty.RegisterReadOnly(
        "Points",
        typeof(ICollectionView),
        typeof(NTab),
        new PropertyMetadata(null)
    );
public static DependencyProperty PointsProperty = PointsPropertyKey.DependencyProperty;

public ICollectionView Points
{
    get { return (ICollectionView) GetValue(PointsProperty ); }
    private set { SetValue(PointsPropertyKey, value); }

}