【问题标题】:Multiple Datagrids In WPF application but only shows one at a time多个数据网格在 WPF 应用程序中,但一次只显示一个
【发布时间】:2026-02-22 02:05:01
【问题描述】:

我创建了一个程序,需要在我的 WPF 应用程序底部显示 5 个数据网格,但是该程序一次只能显示一个。 或者它会显示 3 个框,但只有一个 Datagrid 会包含任何数据。

这是我目前的代码:

private void SearchButton_Click(object sender, RoutedEventArgs e)
    {

        if (GPBox.IsChecked == true)
        {
            connect = new MySqlConnection(connectionString);
            cmd = new MySqlCommand("select distinct nameOfService as Surgeries, street, city, postcode, contactNumber from gpSurgery", connect);
            connect.Open();
            DataTable dt = new DataTable();
            dt.Load(cmd.ExecuteReader());
            connect.Close();
            DataGridGP.Visibility = Visibility.Visible;
            DataGridGP.DataContext = dt;
        }  

        else if (DentistBox.IsChecked == true)
        {
            connect = new MySqlConnection(connectionString);
            cmd = new MySqlCommand("select distinct nameOfService as Dentists, street, city, postcode, contactNumber from Dentist", connect);
            connect.Open();
            DataTable dt = new DataTable();
            dt.Load(cmd.ExecuteReader());
            connect.Close();
            DataGridDentist.Visibility = Visibility.Visible;
            DataGridDentist.DataContext = dt;

        }
        else if (SchoolsBox.IsChecked == true)
        {
            connect = new MySqlConnection(connectionString);
            cmd = new MySqlCommand("select distinct nameOfService as Schools, street, city, postcode, contactNumber from Schools", connect);
            connect.Open();
            DataTable dt = new DataTable();
            dt.Load(cmd.ExecuteReader());
            connect.Close();
            DataGridSchools.Visibility = Visibility.Visible;
            DataGridSchools.DataContext = dt;

        }
        else if (NurseryBox.IsChecked == true)
        {
            connect = new MySqlConnection(connectionString);
            cmd = new MySqlCommand("select distinct nameOfService as Nurserys, street, city, postcode, contactNumber from Nursery", connect);
            MySqlDataAdapter sqlDA = new MySqlDataAdapter();
            DataTable dt = new DataTable();
            dt.Load(cmd.ExecuteReader());
            connect.Close();
            DataGridNursery.Visibility = Visibility.Visible;
            DataGridNursery.DataContext = dt;
        }

        else if (OpticianBox.IsChecked == true)
        {
            connect = new MySqlConnection(connectionString);
            cmd = new MySqlCommand("select distinct nameOfService as Opticians, street, city, postcode, contactNumber from Opticians", connect);
            MySqlDataAdapter sqlDA = new MySqlDataAdapter();
            DataTable dt = new DataTable();
            dt.Load(cmd.ExecuteReader());
            connect.Close();
            DataGridOpticians.Visibility = Visibility.Visible;
            DataGridOpticians.DataContext = dt;
        }
        else
        {
            MessageBox.Show("Select a service.");
        }

    }

XAML 代码:

<DataGrid Name="DataGridGP" Height="57" VerticalAlignment="Top" Margin="0,129,10,0" ItemsSource="{Binding}" Visibility="Collapsed"  />
    <DataGrid Name="DataGridDentist" HorizontalAlignment="Left" Height="57" Margin="0,191,0,0" VerticalAlignment="Top" Width="782" Visibility="Collapsed"/>
    <DataGrid Name="DataGridSchools" HorizontalAlignment="Left" Height="57" Margin="0,253,0,0" VerticalAlignment="Top" Width="782" Visibility="Collapsed"/>
    <DataGrid Name="DataGridNursery" Height="57" Margin="0,315,10,0" VerticalAlignment="Top" Visibility="Collapsed"/>
    <DataGrid Name="DataGridOpticians" HorizontalAlignment="Left" Height="57" Margin="0,377,0,0" VerticalAlignment="Top" Width="782" Visibility="Collapsed"/>

谁能明白为什么它只显示一个 Datagrid 或根本不显示?

谢谢

【问题讨论】:

  • @Gleb 我现在已经添加了 XAML

标签: c# wpf datagrid


【解决方案1】:

问题似乎出在您的 c# 代码中。您在每个条件中都使用了else if,这意味着该块中的代码只有在没有满足之前的条件时才会运行。 例如:

void test()
{
    int i = 5;

    if (i < 2)
    {
        System.Diagnostics.Debug.Print("< 2");
    }
    else if (i > 2)
    {
        System.Diagnostics.Debug.Print("> 2");
    }
    else if(i == 5)
    {
        System.Diagnostics.Debug.Print("= 5");
    }
}

在上面,i &lt; 2 将评估为 false
i &gt; 2 将评估为 truePrint 代码将运行。
但是i == 5 永远不会被检查,因为我们已经找到了匹配项。

在您的代码中,如果您希望用户能够选中多个框并加载每个DataGrids,那么您需要将else ifs 替换为普通的ifs。

代码冗余注意事项

一般来说,您应该避免使用许多不同版本的非常相似的代码,就像您的代码一样。在每个if 块中,您运行的代码几乎相同。如果您需要更改它,则必须更改 5 次。

相反,您应该使用一个方法并将所需的变量传递给它,如下所示:

void loadDataGrid(string command, DataGrid dataGrid)
{
    connect = new MySqlConnection(connectionString);
    cmd = new MySqlCommand(command, connect);
    MySqlDataAdapter sqlDA = new MySqlDataAdapter();
    DataTable dt = new DataTable();
    dt.Load(cmd.ExecuteReader());
    connect.Close();
    dataGrid.Visibility = Visibility.Visible;
    dataGrid.DataContext = dt;
}

您的SearchButton_Click 则变为:

private void SearchButton_Click(object sender, RoutedEventArgs e)
{

    if (GPBox.IsChecked == true)
    {
        loadDataGrid("select distinct nameOfService as Surgeries, street, city, postcode, contactNumber from gpSurgery", DataGridGP)
    }

    ...
}

每个if 条件现在只有一行代码,而不是八行。

WPF 布局注意事项

一般来说,您不应该使用固定的Margin 值来相对于彼此定位 WPF 元素。这开始违背 WPF 布局系统的目的,它使您可以构建非常灵活的设计。相反,您将使用各种类型的Panel 之一。

对于您的情况,我可能会推荐一个 'StackPanel, since you want to stack yourDataGrid`s 垂直重叠。

【讨论】:

  • @FawcettFawcett 你能说得更具体一点吗?究竟是什么行不通?你的新代码是什么样的?
【解决方案2】:

同意关于代码冗余的其他答案,但您也可以使用 SINGLE 网格和 SINGLE DataTable 显着简化。将公共 DataTable 用作您的绑定源...

public DataTable YourData {get; private set;}

然后在你的xaml中,你可以设置

<DataGrid ItemsSource="{Binding YourData}" ... >

查询时,您只需将数据网格中的第一列更改为“nameOfService”列,因为每个查询都返回相同的列名,因此数据网格始终使用相同的表列...例如

   string defTable = "";
   if( GPBox.IsChecked )
      defTable = "gpSurgery";
   else if (DentistBox.IsChecked == true)
      defTable = "Dentist";
   else if (SchoolsBox.IsChecked == true)
      defTable = "Schools";
   else if (NurseryBox.IsChecked == true)
      defTable = "Nursery";
   else if (OpticianBox.IsChecked == true)
      defTable = "Opticians";
   else
   {
      MessageBox.Show("Select a service.");
      return;
   }

   // valid choice...
   // this is NOT going to be an issue of SQL-Injection because YOU are 
   // controlling the string values for the table name to query from.
   connect = new MySqlConnection(connectionString);
   cmd = new MySqlCommand("select distinct nameOfService, street, city, postcode, contactNumber from " + defTable, connect);
   MySqlDataAdapter sqlDA = new MySqlDataAdapter();
   YourData = new DataTable();
   YourData.Load(cmd.ExecuteReader());
   connect.Close();

这对代码维护有很大帮助。这样,您可以拥有一个网格,而不必担心折叠和/或显示哪个网格。您似乎也没有明确声明要显示的列,因此它们可能会在更新绑定时自动创建列。

【讨论】:

  • 如果他们只想一次显示一个DataGrid,这会很好,但我认为他们的问题是他们想根据用户选择显示动态数量的DataGrids .
  • @KeithStein,我不同意,你可能是对的,但他们的开场白说一次只能看到一个......只是展示他们设计的替代方案。
最近更新 更多