【问题标题】:Binding DataTables to Datagrids on a WPF Tabcontrol将 DataTables 绑定到 WPF Tabcontrol 上的 Datagrids
【发布时间】:2019-05-28 08:18:54
【问题描述】:

我有一个 wpf TabControl 和一个 ListBox。如果我单击ListBox 中的一个项目,我想从 SQL Server 上的某个表中获取数据,请向TabControl 添加一个新选项卡,并在此新选项卡上的DataGrid 上显示数据。到目前为止,我有这个:

TabControlListBox 的 XAML:

 <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 项目的文本作为标题以及 DataGrid - 但是 @ 987654335@ 仍为空。

如果你能帮助我,那真是太棒了。我已经查看了关于 SO 的所有类似问题,但似乎没有一个解决方案可以解决我的问题。如果我不使用选项卡控件并直接在表单上添加DataGrid,一切都会完美运行。直接在代码中创建和添加所有内容也可以正常工作,但我想以更正确的方式解决这个问题。

【问题讨论】:

  • 什么是“默认视图”? ObservableCollection Tablecontent 不包含该属性。
  • 抱歉,这是早期版本的代码遗留下来的,当时我只有一个数据表...我更正了上面的代码。

标签: c# wpf data-binding tabcontrol


【解决方案1】:

SelectedTables 应该返回一个IEnumerable&lt;T&gt;,其中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 方法中将新的 T(在上面的示例代码中命名为 TabViewModel)添加到 MainViewModel

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

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

<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>

【讨论】:

  • 非常感谢,现在可以了!总结一下我的理解:问题是我将标题和内容(数据表)保存在两个单独的可观察集合中,而不是在一个对象中,对吧?
  • @dunkleosteus:是的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-21
  • 2011-02-09
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 2017-07-18
相关资源
最近更新 更多