在WPF中动态创建多个DataGrid

如何解决在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解决方案,因为它可以将演示文稿与数据分开,并且更容易实现,并且通过DataGridDataTemplate进行自定义更加容易,方便和可维护在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 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-