【问题标题】:populate DataGrid when TabItem selected选择 TabItem 时填充 DataGrid
【发布时间】:2020-11-28 23:23:58
【问题描述】:

WPF 表单具有带有三个 TabItem 的 TabControl。每个 TabItem 都包含 DataGrid。如果选择了 TabItem,我想填充 DataGrid。

C#

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    SetA_DG();
}

public void SetA_DG()
{
   var sourcea UIAdapter.GetSourceA();
   DataGrid_A.ItemsSource = sourcea;
}   

public void SetB_DG()
{
   var sourceb UIAdapter.GetSourceB();
   DataGrid_B.ItemsSource = sourceb;
}

public void SetC_DG()
{
   var sourcec UIAdapter.GetSourceC();
   DataGrid_C.ItemsSource = sourcec;
}
private void ABC_TC_SelectionChenged(object sender, SelectionChangedEventArgs e)
//{
   //var sTabItem = ABC_TC.SelectedItem as TabItem;

   //switch (sTabItem.Name)
   //{
      //case "A_TI":
         //SetA_DG();
         //break;
      //case "B_TI":
         //SetB_DG();
         //break;
      //case "C_TI":
         //SetC_DG();
         //break;
  //}
     
   {
       var employees = GetEmployees();
       TabControl tabControl = (TabControl)sender;
       var selectedIndex = tabControl.SelectedIndex;
       TabItem tabItem = (TabItem)tabControl.SelectedItem;
       Grid grid = (Grid)tabItem.Content;
       var dataGrid = grid.GetChildOfType<DataGrid>();

       dataGrid.ItemsSource = employees;
   }
}

当我运行应用程序时,我收到错误消息: System.NullReferenceException: '对象引用未设置为对象的实例。' dataGrid 为空。 在线执行停止:dataGrid.ItemsSource = employees;

XAML

`        <TabControl x:Name="ABC_TC" TabStripPlacement="Top" BorderThickness="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" SelectionChanged="ABC_TC_SelectionChanged">
        <TabItem x:Name="A_TI" IsSelected="True" Header="AAA" >
            <DataGrid Name="A_DG" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="250" SortMemberPath="Name" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Description" Binding="{Binding Path=Description}" Width="250" SortMemberPath="Description" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Active" Binding="{Binding Path=IsActive}" Width="50" SortMemberPath="IsActive" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Created On" Binding="{Binding Path=CreatedOn, StringFormat='{}{0:MM/dd/yyyy}'}" Width="110" SortMemberPath="CreatedOn" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Created By" Binding="{Binding Path=CreatedBy}" Width="100" SortMemberPath="CreatedBy" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Updated On" Binding="{Binding Path=UpdatedOn, StringFormat='{}{0:MM/dd/yyyy}'}" Width="110" SortMemberPath="UpdatedOn" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Updated By" Binding="{Binding Path=UpdatedBy}" Width="100" SortMemberPath="UpdatedBy" IsReadOnly="True"/>
                </DataGrid.Columns>
            </DataGrid>
        </TabItem>
        <TabItem x:Name="B_TI" IsSelected="True" Header="BBB" >
            <DataGrid Name="B_DG" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="250" SortMemberPath="Name" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Email" Binding="{Binding Path=Email}" Width="250" SortMemberPath="Email" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Created On" Binding="{Binding Path=CreatedOn, StringFormat='{}{0:MM/dd/yyyy}'}" Width="110" SortMemberPath="CreatedOn" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Created By" Binding="{Binding Path=CreatedBy}" Width="100" SortMemberPath="CreatedBy" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Updated On" Binding="{Binding Path=UpdatedOn, StringFormat='{}{0:MM/dd/yyyy}'}" Width="110" SortMemberPath="UpdatedOn" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Updated By" Binding="{Binding Path=UpdatedBy}" Width="100" SortMemberPath="UpdatedBy" IsReadOnly="True"/>
                </DataGrid.Columns>
            </DataGrid>
        </TabItem>
        <TabItem x:Name="C_TI" IsSelected="True" Header="CCC" >
            <DataGrid Name="C_DG" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="250" SortMemberPath="Name" IsReadOnly="True"/>
                    <DataGridTextColumn Header="IsActive" Binding="{Binding Path=IsActive}" Width="50" SortMemberPath="Isactive" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Created On" Binding="{Binding Path=CreatedOn, StringFormat='{}{0:MM/dd/yyyy}'}" Width="110" SortMemberPath="CreatedOn" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Created By" Binding="{Binding Path=CreatedBy}" Width="100" SortMemberPath="CreatedBy" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Updated On" Binding="{Binding Path=UpdatedOn, StringFormat='{}{0:MM/dd/yyyy}'}" Width="110" SortMemberPath="UpdatedOn" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Updated By" Binding="{Binding Path=UpdatedBy}" Width="100" SortMemberPath="UpdatedBy" IsReadOnly="True"/>
                </DataGrid.Columns>
            </DataGrid>
        </TabItem>
    </TabControl>

`

如何解决问题?

谢谢。

【问题讨论】:

  • 当我从你建议的链接中添加 GetChildOfType 方法时,我收到了错误消息:

标签: c# wpf


【解决方案1】:

要实现数据网格的填充必须在此事件 TabControl_SelectionChanged 内。

 private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var productList = getProductList();
        TabControl tabControl = (TabControl)sender;
        var selectedIndex = tabControl.SelectedIndex;
        TabItem tabItem = (TabItem)tabControl.SelectedItem;
        Grid grid = (Grid)tabItem.Content;
        var dataGrid = grid.GetChildOfType<DataGrid>();

        dataGrid.ItemsSource = productList;
    }

我使用了 GetChildOfType 方法来更轻松地获取控件,您可以检查它on this answer

输出 1:

输出 2:

我希望它有所帮助。编码愉快。

【讨论】:

  • 你好 tontonsevilla。感谢重播。当我按照您的建议添加 GetChildOfType 方法时,我收到错误消息:“扩展方法必须在非泛型静态类中定义”如何解决此错误?或者您是否知道在选定的 TabItem 中填充 DataGrid 的另一种方法?谢谢。
  • @eugz 你能说明你是如何实现 GetChildOfType 方法的吗?还要确保它在一个单独的公共静态类扩展中。
  • 我从链接复制方法代码:public static T GetChildOfType&lt;T&gt;(this DependencyObject depObj) where T : DependencyObject { if (depObj == null) return null; for (int i = 0; i &lt; VisualTreeHelper.GetChildrenCount(depObj); i++) { var child = VisualTreeHelper.GetChild(depObj, i); var result = (child as T) ?? GetChildOfType&lt;T&gt;(child); if (result != null) return result; } return null; } 并将其插入到我的中:public partial class Employees { .... }
  • @eugz 不要把它放在你的部分类中,而是创建一个新类,如 public static class Extension { public static T GetChildOfType(...)}
  • 我创建了扩展类和过去的 GetChildOfType() 方法。然后我将您帖子中的代码用于我的 TabControl_SelectionChanged()。但是当我运行应用程序时,我在 dataGrid.ItemsSource = employeeList: System.NullReferenceExeption: 对象引用未设置为对象实例的行上遇到错误。 dataGrid 为空。如何修复错误?谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-14
  • 1970-01-01
  • 2015-10-26
  • 2011-01-24
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
相关资源
最近更新 更多