简体   繁体   English

用于分层信息的WPF DataGrids

[英]WPF DataGrids for hierarchical information

I have an application that contains an ObservableCollection<Foo> , and Foo in turn contains an ObservableCollection<Bar> . 我有一个包含ObservableCollection<Foo>的应用程序,而Foo又包含一个ObservableCollection<Bar> I would like a pair of datagrids, one showing the collection of Foo objects in the application and the other showing the collection of Bar objects in the Foo that's currently selected in the first datagrid (and I want to be able to add, update and delete entries in both datagrids). 我想要一对datagrids,一个显示应用程序中Foo对象的集合,另一个显示当前在第一个数据网格中选择的Foo中的Bar对象集合(我希望能够添加,更新和删除两个数据网格中的条目)。

So far I've got the following XAML: 到目前为止,我有以下XAML:

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <DataGrid Grid.Column="0" ItemsSource="{Binding Foos}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Foo Name" Binding="{Binding Name}" Width="Auto" IsReadOnly="False" />
            </DataGrid.Columns>
        </DataGrid>
        <GridSplitter HorizontalAlignment="Right" VerticalAlignment="Stretch" Grid.Column="1" ResizeBehavior="PreviousAndNext" Width="5" Background="Gray" />
        <DataGrid Grid.Column="2">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Bar Name" Width="Auto" IsReadOnly="False"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

And the following code: 以下代码:

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

namespace Test
{
    public class Foo
    {
        static int _nextId;
        public int Id { get; private set; }
        public String Name { get; set; }
        public ObservableCollection<Bar> Bars { get; set; }
        public Foo()
        {
            Id = _nextId++;
            Name = String.Empty;
            Bars = new ObservableCollection<Bar>();
        }
    }

    public class Bar
    {
        static int _nextId;
        public int Id { get; private set; }
        public String Name { get; set; }
        public Bar()
        {
            Id = _nextId++;
            Name = String.Empty;
        }
    }
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<Foo> Foos { get; set; }
        public MainWindow()
        {
            Foos = new ObservableCollection<Foo>();
            Foo newFoo;
            for (int index = 0; index < 5; ++index)
            {
                newFoo = new Foo();
                newFoo.Name = String.Format("Foo {0}", index);
                Foos.Add(newFoo);
            }
            InitializeComponent();
            DataContext = this;
        }
    }
}

Obviously I've not bound the 2nd DataGrid yet, because I've not got the faintest idea how to do it! 显然我还没有绑定第二个DataGrid,因为我不知道如何做到这一点! All the examples I can find assume I'm binding DataTables, not custom objects, and bind to a relation on the DataTables. 我能找到的所有例子都假设我绑定DataTables,而不是自定义对象,并绑定到DataTables上的关系。 I don't really understand binding all that well yet. 我真的不明白那么好的约束力。 Can anybody tell me how to bind the 2nd table? 谁能告诉我如何绑定第二张桌子?

(And yes, if you've seen my other recent questions, I am giving WPF another shot after not getting on well with it in the early days). (是的,如果你已经看到了我最近的其他问题,那么在早期没有得到很好的帮助后,我会给WPF另一个镜头)。

Thanks in advance. 提前致谢。

Use Binding to Element 使用绑定到元素
Name the top grid gridTop 将顶部网格命名为gridTop

DataContext="{Binding ElementName=gridTop, Path=SelectedItem.Bars}"

Hi If you want editable grids first of all you will have to implement INotifyPropertyChanged like 嗨如果你想要可编辑的网格,首先你必须实现INotifyPropertyChanged

    public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }
}

public class ViewModel 
{
    public ViewModel()
    {
        Foos = new ObservableCollection<Foo>();
    }

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

public class Foo : INotifyPropertyChanged
{
    static int _nextId;
    public int Id { get; private set; }
    public ObservableCollection<Bar> Bars { get; set; }
    public Foo()
    {
        Id = _nextId++;
        Name = String.Empty;
        Bars = new ObservableCollection<Bar>();
    }
    private string name;

    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
            Notify("Name");
        }
    }

    private void Notify(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

}

public class Bar : INotifyPropertyChanged
{
    static int _nextId;
    public int Id { get; private set; }
    public Bar()
    {
        Id = _nextId++;
        Name = String.Empty;
    }

    private string name;

    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
            Notify("Name");
        }
    }

    private void Notify(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

In xaml Binding for first Grid is corrrect and for second grid you can set ItemsSource as the the selectedItem of First grid using ElementName 在xaml中绑定第一个网格是正确的,对于第二个网格,您可以使用ElementName将ItemsSource设置为第一个网格的selectedItem

<DataGrid Grid.Column="2" ItemsSource="{Binding ElementName=gridTop, Path=SelectedItem.Bars}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Bar Name" Binding="{Binding Name}" Width="Auto" IsReadOnly="False"/>
        </DataGrid.Columns>
    </DataGrid>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM