Правильное связывание в WPF (коллекция внутри коллекции) на вкладке и в таблице данных

1

Я хотел бы иметь на нескольких вкладках разные Datagrids, но у меня проблемы с правильной привязкой.

Каждая TabEntry имеет коллекцию DataGridEntry. Элементы Tab отображаются (Tab1 и Tab2), но привязка для DataGridEntries неверна.

TabEntry.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace TabControlTest
{
    public class TabEntry : INotifyPropertyChanged
    {
        public TabEntry()
        {
            DataGridEntries = new ObservableCollection<DataGridEntry>();
        }
        public string Description { get; set; }
        public ObservableCollection<DataGridEntry> DataGridEntries{get;set;}

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class DataGridEntry : INotifyPropertyChanged
    {
        public string Description { get; set; }
        public string Value { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        ObservableCollection<TabEntry> Tabs = new ObservableCollection<TabEntry>();

        TabEntry tab1 = new TabEntry();
        tab1.Description = "Tab1";

        DataGridEntry data1 = new DataGridEntry();
        data1.Description = "Tab1 Description 1";
        data1.Value = "Tab1 Value 1";

        DataGridEntry data2 = new DataGridEntry();
        data2.Description = "Tab1 Description 2";
        data2.Value = "Tab1 Value 2";

        tab1.DataGridEntries.Add(data1);
        tab1.DataGridEntries.Add(data2);

        TabEntry tab2 = new TabEntry();
        tab2.Description = "Tab2";

        DataGridEntry data3 = new DataGridEntry();
        data1.Description = "Tab2 Description 1";
        data1.Value = "Tab1 Value 1";

        DataGridEntry data4 = new DataGridEntry();
        data2.Description = "Tab2 Description 2";
        data2.Value = "Tab1 Value 2";

        tab2.DataGridEntries.Add(data3);
        tab2.DataGridEntries.Add(data4);

        Tabs.Add(tab1);
        Tabs.Add(tab2);
        this.DataContext = Tabs;        
        InitializeComponent();
    }
}

Вкладки - это коллекция с tabEntries (класс TabEntry). Каждый TabEntry имеет коллекцию с DataGridEntries (класс DataGridEntry). Как я привязываюсь к этим коллекциям правильно в xaml?

<Window x:Class="TabControlTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TabControlTest"
        Title="MainWindow" Height="350" Width="525">

    <Grid>
        <TabControl x:Name="tabControl1" ItemsSource="{Binding}" TabStripPlacement="Left" HorizontalAlignment="Left" Height="242" Margin="10,10,0,0" VerticalAlignment="Top" Width="358">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Description}"></TextBlock>
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ContentTemplate>
                <DataTemplate>
                    <DataGrid x:Name="dataGrid1" ItemsSource="{Binding DataGridEntries}">
                        <DataGrid.Columns>
                        <DataGridTextColumn Header="Description" Binding="{Binding Description}"></DataGridTextColumn>
                        <DataGridTextColumn Header="Value" Binding="{Binding Value}"></DataGridTextColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>
    </Grid>
</Window>

У меня есть следующий вывод:

Изображение 174551

Содержимое неправильно отображено в TabControl и DataGrid.

Datagrid на Tab2 пуст

Теги:
xaml
wpf
data-binding
datagrid

2 ответа

0
Лучший ответ

Здесь более чистая реализация того, что вы пытаетесь сделать Xaml

<Window x:Class="WpfApplication34.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wpfApplication34="clr-namespace:WpfApplication34"
    Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>

    <Grid>
        <TabControl x:Name="tabControl1" ItemsSource="{Binding Tabs}" TabStripPlacement="Left" HorizontalAlignment="Left" Height="242" Margin="10,10,0,0" VerticalAlignment="Top" Width="358">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Description}" ></TextBlock>
                </DataTemplate>
            </TabControl.ItemTemplate>

            <TabControl.ContentTemplate>
                <DataTemplate>
                    <DataGrid x:Name="dataGrid1" ItemsSource="{Binding DataGridEntries}">
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Description" Binding="{Binding Desription}"></DataGridTextColumn>
                            <DataGridTextColumn Header="Value" Binding="{Binding Value}"></DataGridTextColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>
    </Grid>
</Grid>

и codeBehind:

 public partial class MainWindow : Window, INotifyPropertyChanged
{
    private ObservableCollection<TabEntry> _tabs ;

    public ObservableCollection<TabEntry> Tabs
    {
        get
        {
            return _tabs;
        }

        set
        {
            if (_tabs == value)
            {
                return;
            }

            _tabs = value;
            OnPropertyChanged();
        }
    }

    public MainWindow()
    {
        InitializeComponent();
         Tabs = new ObservableCollection<TabEntry>()
        {
            new TabEntry()
            {
                Description = "Tab1",
                DataGridEntries = new ObservableCollection<DataGridEntry>()
                {
                    new DataGridEntry()
                    {
                        Description = "Tab1 Description 1",
                        Value = "Tab1 Value 1"
                    },
                    new DataGridEntry()
                    {
                        Description = "Tab1 Description 2",
                        Value = "Tab1 Value 2"
                    }
                }
            },
             new TabEntry()
            {
                Description = "Tab2",
                DataGridEntries = new ObservableCollection<DataGridEntry>()
                {
                    new DataGridEntry()
                    {
                        Description = "Tab2 Description 1",
                        Value = "Tab2 Value 1"
                    },
                    new DataGridEntry()
                    {
                        Description = "Tab2 Description 2",
                        Value = "Tab2 Value 2"
                    }
                }
            }

        };




    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
public class TabEntry : INotifyPropertyChanged
{



    private String _description;
    public String Description
    {
        get
        {
            return _description;
        }

        set
        {
            if (_description == value)
            {
                return;
            }

            _description = value;
            OnPropertyChanged();
        }
    }
    public ObservableCollection<DataGridEntry> DataGridEntries { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class DataGridEntry : INotifyPropertyChanged
{


    private String _description;
    public String Description
    {
        get
        {
            return _description;
        }

        set
        {
            if (_description == value)
            {
                return;
            }

            _description = value;
            OnPropertyChanged();
        }
    }
    private String _value;
    public String Value
    {
        get
        {
            return _value;
        }

        set
        {
            if (_value == value)
            {
                return;
            }

            _value = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
0

Ваш член DataGridEntries должен быть свойством, которое будет использоваться в привязке:

public class TabEntry : INotifyPropertyChanged
{
    public TabEntry()
    {
        DataGridEntries = new ObservableCollection<DataGridEntry>();
    }
    public string Description { get; set; }
    public ObservableCollection<DataGridEntry> DataGridEntries { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
}

Боковое примечание. Просто реализовать INotifyPropertyChanged недостаточно - вам также нужно вызвать событие в методах getter. Либо внедрите геттеры, либо используйте, например, Fody...

  • 0
    Спасибо, что я забыл реализовать Коллекцию как Собственность. У меня есть записи сейчас, но позиционирование неверно. На вкладке Tab1 у меня есть записи, Tab2 пусто .... На вкладке Tab1 у меня есть такая запись: [Tab 2 Description 1; Вкладка 1 Значение 1]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню