将数据表绑定到 WPF Tabcontrol 上的数据网格

Binding DataTables to Datagrids on a WPF Tabcontrol

我有一个 wpf TabControl 和一个 ListBox。如果我点击ListBox中的其中一项我想从SQL服务器上的某个table获取数据,添加一个新标签到TabControl并显示此新选项卡上 DataGrid 上的数据。到目前为止我有这个:

XAML 对于 TabControlListBox:

 <Grid>
    <ListBox x:Name="lb"  ItemsSource="{Binding Alltables}" MouseDoubleClick="opendata"/>

    <TabControl x:Name="tabControl"  ItemsSource="{Binding SelectedTables}">
        <TabControl.ContentTemplate >
            <DataTemplate >
                <Grid>
                    <DataGrid x:Name="dataGrid" AutoGenerateColumns="True" ItemsSource="{Binding Tablecontent}"/>                  
                </Grid>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</Grid>

我的视图模型:

   public class MainViewModel : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {

            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }

        }

        private ObservableCollection<String> selectedtables;
    public ObservableCollection<String> SelectedTables
    {
        get { return selectedtables; }
        set
        {
            if (selectedtables != value)
            {

                selectedtables = value;
                OnPropertyChanged("SelectedTables");
            }
        }
    }

    private ObservableCollection<DataTable> tablecontent;
    public ObservableCollection<DataTable> Tablecontent
    {
        get { return tablecontent; }
        set
        {
            if (tablecontent != value)
            {
                tablecontent = value;
                OnPropertyChanged("Tablecontent");
            }
        }
    }

}

ListBox 的点击事件:

   private void opendata(object sender, MouseButtonEventArgs e)
    {
//...
 //Some preparations before querying the data etc.
//...

   DataTable mydata = new DataTable();

        using (connection = new SqlConnection(connectionString))
        {
            SqlCommand command = new SqlCommand(queryString, connection);
            command.Connection.Open();
            SqlDataReader reader = command.ExecuteReader();
            mydata.Load(reader);
        }  

        string tabletoload = lb.SelectedItem.ToString();

        myview2.SelectedTables.Add(tabletoload); //myview2 is the instance of my ViewModel

        myview2.Tablecontent.Add(mydata); //myview2 is the instance of my ViewModel
    }
}

现在发生的事情是,当我单击 ListBox 中的一个项目时,会正确创建一个新选项卡,其中包含所选 ListBox 项目的文本 Header还有一个 DataGrid - 但是 DataGrid 仍然是空的。

如果你能帮助我,那就太好了。我已经在 SO 上查看了所有类似的问题,但 none 的解决方案似乎解决了我的问题。如果我不使用选项卡控件而只是直接在表单上添加 DataGrid ,一切都会完美无缺。直接在代码中创建和添加所有内容也很好,但我想以更正确的方式解决这个问题。

SelectedTables 应该 return 一个 IEnumerable<T> 其中类型 T 定义名称 DataTable对于当前选项卡:

public class TabViewModel
{
    public string Header { get; set; }
    public DataTable Tablecontent { get; set; }
}

public class MainViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }

    private ObservableCollection<TabViewModel> selectedtables;
    public ObservableCollection<TabViewModel> SelectedTables
    {
        get { return selectedtables; }
        set
        {
            if (selectedtables != value)
            {

                selectedtables = value;
                OnPropertyChanged("SelectedTables");
            }
        }
    }
}

然后,您将向 opendata 方法中的 MainViewModel 添加一个新的 T(在上面的示例代码中名为 TabViewModel):

string tabletoload = lb.SelectedItem.ToString();
myview2.SelectedTables.Add(new TabViewModel() { Header = tabletoload, Tablecontent = mydata });

...并为视图中的 TabControl 定义一个 ItemTemplate 以显示 header:

<TabControl x:Name="tabControl"  ItemsSource="{Binding SelectedTables}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Header}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate >
        <DataTemplate >
            <Grid>
                <DataGrid x:Name="dataGrid" AutoGenerateColumns="True" ItemsSource="{Binding Tablecontent}"/>
            </Grid>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>