我有一个wpf TabControl
和一个ListBox
。如果单击ListBox
中的某个项目,要从SQL Server的某个表中获取数据,请向TabControl
添加一个新标签,并在{{1}上显示数据在此新标签上。到目前为止,我有这个:
DataGrid
和TabControl
的XAML:
ListBox
我的ViewModel:
<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
项目的文本作为标题,另外还有一个{{1 }}-但是ListBox
仍然为空。
如果您能帮助我,真的会很棒。我在SO上浏览了所有类似的问题,但是没有一个解决方案似乎可以解决我的问题。如果我不使用制表符控件,而直接在表单上直接添加DataGrid
,那么一切都将正常运行。同样,直接在代码中创建和添加所有内容也可以,但是我想以更正确的方式解决此问题。
答案 0 :(得分:1)
SelectedTables
应该返回一个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");
}
}
}
}
然后,您可以在T
方法中将新的TabViewModel
(在上面的示例代码中命名为MainViewModel
)添加到opendata
:
string tabletoload = lb.SelectedItem.ToString();
myview2.SelectedTables.Add(new TabViewModel() { Header = tabletoload, Tablecontent = mydata });
...并在视图中为ItemTemplate
定义一个TabControl
,以显示标题:
<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>