如何解决在WPF中动态创建多个DataGrid
我正在尝试在WPF中动态创建DataGrid
,一个在Grid
中一个在另一个下方。问题是我什至不知道从哪里开始,我看到可以通过代码完成,但是我想正确地使用XAML。
void PopulateDatagridSQL(string Data,string index,string TabName)
{
try
{
Data = Data.Replace((Char)6,(Char)124);
List<DataTable> Results = new List<DataTable>();
Results = JsonConvert.DeserializeObject<List<DataTable>>(Data);
foreach (SQLWindow SingleSQLWindows in StaticVar.MySQLWindows)
{
if (SingleSQLWindows.MyINDEX == index)
{
SingleSQLWindows.Dispatcher.Invoke(new Action(() =>
{
foreach (TabItem item in SingleSQLWindows._tabItems)
{
if (item.Name == TabName)
{
//create multiple datagrids up to results.count
((SQLPage)((Frame)item.Content).Content).DataGrid1.ItemsSource = Results[0].DefaultView;//foreach
((SQLPage)((Frame)item.Content).Content).TxtSqlLog.Text = "Records in Datagrid: " + Results[0].Rows.Count;//foreach
}
}
}));
}
}
}
catch (Exception asd)
{
foreach (SQLWindow SingleSQLWindows in StaticVar.MySQLWindows)
{
if (SingleSQLWindows.MyINDEX == index)
{
SingleSQLWindows.Dispatcher.Invoke(new Action(() =>
{
foreach (TabItem item in SingleSQLWindows._tabItems)
{
if (item.Name == TabName)
{
((SQLPage)((Frame)item.Content).Content).TxtSqlLog.Text = "Error in $SqlResponse";
}
}
}));
}
}
}
}
在此功能中,我收到DataTable
的列表,并且必须为每个DataTable
创建一个DataGrid
。
<Page x:Class="Emergency_APP_Server_WPF.Forms.SQLPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Emergency_APP_Server_WPF.Forms"
mc:Ignorable="d" x:Name="SQLPageXaml" Loaded="SQLPage_Loaded"
d:DesignHeight="450" d:DesignWidth="800"
Title="SQLPage" >
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" MinHeight="100"></RowDefinition>
<RowDefinition Height="0"></RowDefinition>
<RowDefinition Height="*" MinHeight="150"></RowDefinition>
<RowDefinition Height="35"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="70"></ColumnDefinition>
</Grid.ColumnDefinitions>
<avalonEdit:TextEditor Grid.Column="0" Background="White"
xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
Name="MyAvalonEdit" FontFamily="Consolas"
FontSize="11pt" Margin="10,10,10" ShowLineNumbers="True"
LineNumbersForeground="Gray" ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto" KeyUp="MyAvalonEdit_KeyUp"/>
<Button Grid.Column="1" x:Name="BtnSendSQL" Margin="0,10" Click="BtnSendSQL_Click">
<StackPanel>
<Image Height="25" Source="..//Resources/send.png"></Image>
<TextBlock Margin="0,0" VerticalAlignment="Top" Foreground="White" Text="SendSQL"></TextBlock>
</StackPanel>
</Button>
</Grid>
<GridSplitter Margin="0,-10,0" Grid.Row="1" HorizontalAlignment="Stretch" Background="Transparent" ResizeBehavior="PreviousAndNext">
</GridSplitter>
<DataGrid Grid.Row="2" x:Name="DataGrid1" RowStyle="{StaticResource DataGridRowSql}" Style="{StaticResource DataGridStyleSQL}" >
<DataGrid.CommandBindings>
<CommandBinding Command="Copy" Executed="CommandBinding_Executed"></CommandBinding>
</DataGrid.CommandBindings>
<DataGrid.InputBindings>
<KeyBinding Key="C" Modifiers="Ctrl" Command="Copy"></KeyBinding>
</DataGrid.InputBindings>
</DataGrid>
<TextBlock TextAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Bottom" Grid.Row="3" x:Name="TxtSqlLog" Text="Wait For Commands..."
FontSize="14" FontFamily="Consolas" Foreground="White"></TextBlock>
</Grid>
</Grid>
解决方法
我不知道要放置所有DataGrid
的确切布局,所以我只是假设您要将它们放置在2
的行Grid
中。当您要堆叠它们时,可以在ItemsControl
中使用ScrollViewer
。后者就在那里,因此如果页面太小而无法全部显示它们,则可以滚动浏览DataGrids
。因此,这是以下解决方案的基本布局。
<Grid>
<Grid.RowDefinitions>
<!-- ...your row definitions. -->
</Grid.RowDefinitions>
<!-- ...your other controls. -->
<ScrollViewer Grid.Row="2">
<ItemsControl/>
</ScrollViewer>
</Grid>
代码隐藏解决方案
在后台代码中,您需要访问ItemsControl
,因此为它分配一个名称。
<ItemsControl x:Name="DataGridContainer"/>
然后只需在您的DataGrid
列表中循环创建DataTable
。
foreach (var dataTable in Results)
{
var dataGrid = new DataGrid { ItemsSource = dataTable.DefaultView };
DataGridContainer.Items.Add(dataGrid);
};
在这种情况下,您还可以使用StackPanel
代替ItemsControl
。
MVVM解决方案
您可以在视图模型中创建一个属性,以显示DataTables
的默认视图。
public ObservableCollection<DataView> DataViews { get; }
确保在构造函数中实例化集合或实现INotifyPropertyChanged
,以使该集合在XAML中可用。然后将ItemsControl
绑定到此集合。
<ItemsControl ItemsSource="{Binding DataViews}"/>
接下来,为DataTemplate
类型创建一个DataView
。由于绑定集合中的每个数据视图都代表一个应显示为DataGrid
的数据表,因此看起来像这样。
<DataTemplate DataType="{x:Type data:DataView}">
<DataGrid ItemsSource="{Binding}"/>
</DataTemplate>
然后,您必须在ItemTemplate
中将此数据模板分配为ItemsControl
。我只是在这里内联它,但是您也可以将其放入任何ResourceDictionary
中并通过StaticResource
进行引用。
<ItemsControl ItemsSource="{Binding DataViews}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type data:DataView}">
<DataGrid ItemsSource="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
现在,您只需要将默认视图添加到DataView
的集合中。由于此集合是ObservableCollection
,因此它将通知ItemsControl
更新每个添加项。
foreach (var dataTable in Results)
{
DataViews.Add(dataTable.DefaultView);
};
添加项目后,ItemsControl
将得到通知,并使用DataTemplate
创建项目。
我建议您使用MVVM解决方案,因为它可以将演示文稿与数据分开,并且更容易实现,并且通过DataGrid
对DataTemplate
进行自定义更加容易,方便和可维护在XAML中。
<Page x:Class="Emergency_APP_Server_WPF.Forms.SQLPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:z="clr-namespace:System.Data;assembly=System.Data"
xmlns:local="clr-namespace:Emergency_APP_Server_WPF.Forms"
mc:Ignorable="d" x:Name="SQLPageXaml" Loaded="SQLPage_Loaded"
d:DesignHeight="450" d:DesignWidth="800"
Title="SQLPage" >
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" MinHeight="100"></RowDefinition>
<RowDefinition Height="0"></RowDefinition>
<RowDefinition Height="*" MinHeight="150"></RowDefinition>
<RowDefinition Height="35"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="70"></ColumnDefinition>
</Grid.ColumnDefinitions>
<avalonEdit:TextEditor Grid.Column="0" Background="White"
xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
Name="MyAvalonEdit" FontFamily="Consolas"
FontSize="11pt" Margin="10,10,10" ShowLineNumbers="True"
LineNumbersForeground="Gray" ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto" KeyUp="MyAvalonEdit_KeyUp"/>
<Button Grid.Column="1" x:Name="BtnSendSQL" Margin="0,10" Click="BtnSendSQL_Click">
<StackPanel>
<Image Height="25" Source="..//Resources/send.png"></Image>
<TextBlock Margin="0,0" VerticalAlignment="Top" Foreground="White" Text="SendSQL"></TextBlock>
</StackPanel>
</Button>
</Grid>
<GridSplitter Margin="0,-10,0" Grid.Row="1" HorizontalAlignment="Stretch" Background="Transparent" ResizeBehavior="PreviousAndNext">
</GridSplitter>
<ScrollViewer Grid.Row="2">
<ItemsControl ItemsSource="{Binding DataViews}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type z:DataView}">
<DataGrid RowStyle="{StaticResource DataGridRowSql}" Style="{StaticResource DataGridStyleSQL}" ItemsSource="{Binding}">
<DataGrid.CommandBindings>
<CommandBinding Command="Copy" Executed="CommandBinding_Executed"></CommandBinding>
</DataGrid.CommandBindings>
<DataGrid.InputBindings>
<KeyBinding Key="C" Modifiers="Ctrl" Command="Copy"></KeyBinding>
</DataGrid.InputBindings>
</DataGrid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<TextBlock TextAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Bottom" Grid.Row="3" x:Name="TxtSqlLog" Text="Wait For Commands..."
FontSize="14" FontFamily="Consolas" Foreground="White"></TextBlock>
</Grid>
</Grid>
public ObservableCollection<DataView> _DataViews = new ObservableCollection<DataView>();
public ObservableCollection<DataView> DataViews
{
get
{
return _DataViews;
}
set
{
_DataViews = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string Param = null)
{
PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(Param));
}
foreach (SQLWindow SingleSQLWindows in StaticVar.MySQLWindows)
{
if (SingleSQLWindows.MyINDEX == index)
{
SingleSQLWindows.Dispatcher.Invoke(new Action(() =>
{
foreach (TabItem item in SingleSQLWindows._tabItems)
{
if (item.Name == TabName)
{
foreach (DataTable itemTable in Results)
{
//SingleSQLWindows.DataViews.Add(itemTable.DefaultView);
////create more datagrid while results.count
///
((SQLPage)((Frame)item.Content).Content).DataViews.Add(itemTable.DefaultView);
//((SQLPage)((Frame)item.Content).Content).TxtSqlLog.Text = "Records in Datagrid: " + Results[0].Rows.Count;//foreach
}
}
}
}));
}
}
Visual Studio不会报告任何错误,但是滚动查看器仍然为空,我无法理解为什么
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。