WPF MVVM模式下的 DataGrid 主从表嵌套 RowDetailsTemplate 。。。。。求大神

senler 2018-04-18 03:55:00
在mvvm模式下 主表绑定的数据源能正常显示,而从表绑定的数据源无法显示 只有表头显示
xaml 代码如下
<DataGrid Name="DgMain" Grid.Row="2" ItemsSource="{Binding QueryMainList}">
<DataGrid.Columns>
<DataGridTextColumn Header="姓名" Binding="{Binding UserName}"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid Name="DgSub" ItemsSource="{Binding QuerySubList}">
<DataGrid.Columns>
<DataGridTextColumn Header="科目" Binding="{Binding subject}"/>
<DataGridTextColumn Header="成绩" Binding="{Binding Score}"/>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>


viewModel 里面
private ObservableCollection<Student> _queryMainlList;
public ObservableCollection<Student> QueryMainList
{
get { return _queryMainlList; }
set
{
_queryMainlList = value;
RaisePropertyChanged("QueryMainList");
}
}

private ObservableCollection<Score> _querySubList;

public ObservableCollection<Score> QuerySubList
{
get { return _querySubList; }
set
{
_querySubList = value;
RaisePropertyChanged("QuerySubList");
}
}


实际上我的子表QuerySubList里面是有数据的,求大神解答下!!!!
...全文
1771 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
tekcai.com 2018-04-19
  • 打赏
  • 举报
回复
using System;
using System.Data;
using System.Data.OleDb;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace YZTelApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            YuYueDataGrid.DataContext = GetDataSet("select * from 预约电话", "YuYueDataTable").Tables["YuYueDataTable"];
            //YuYueDataGrid.RowDetailsVisibilityChanged += new EventHandler<DataGridRowDetailsEventArgs>(YuYueDataGrid_RowDetailsVisibilityChanged);
        }
        private string conStr = Properties.Settings.Default.YZTelDBConnectionString;

        public DataSet GetDataSet(string SqlStr,string TblName)
        {
            OleDbConnection OleCon = new OleDbConnection(conStr);
            DataSet DS;
            DS = new DataSet();
            OleDbCommand cmd = new OleDbCommand(SqlStr, OleCon);//预约电话表
            try
            {
                OleCon.Open();
                OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
                adapter.Fill(DS, TblName);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
            finally
            {
                OleCon.Close();
            }
            return DS;
        }
        //string CellValue;
        //void YuYueDataGrid_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
        //{
        //    DataGrid MainDataGrid = sender as DataGrid;//主表
        //    //MessageBox.Show(YuYueDataGrid.SelectedIndex.ToString());
        //    DataGridRow row = (DataGridRow)MainDataGrid.ItemContainerGenerator.ContainerFromIndex(YuYueDataGrid.SelectedIndex);//用于显示,收缩子表
        //    //DataGrid DDG = FindVisualChildByName<DataGrid>(row, "DetailsDataGrid") as DataGrid;//从表
        //    var cell = MainDataGrid.CurrentCell;
        //    int ColumnIndex = cell.Column.DisplayIndex;//获取单元格表头(列)索引.
        //    DataRowView SelectedRow = (DataRowView)YuYueDataGrid.SelectedItem;
        //    string CellValue = SelectedRow.Row[ColumnIndex].ToString();//获取选中单元格的值
        //    /* 
        //     * cell.Item[cell.Column.];// 获取选中的当前单元格的值
        //     * 第3列以后不进行详细查询因而也不应显示 详细行的子表,但是主表的行这时应为被选状态,被选单元格应可编辑
        //     * 如果被选单元格为空值也不进行数据库详细查询,也不显示详细行的子表,但是主表的行这时应为被选状态,
        //     * 被选单元格应可编辑
        //     */
        //    if (ColumnIndex>3 || string.IsNullOrEmpty(CellValue))
        //    {
        //        //MainDataGrid.SelectedIndex =-1;//这样设置成了无选择状态了,不符合要求
        //        row.DetailsVisibility = Visibility.Collapsed;
        //        return;
        //    }
         
        //    string HeaderName = MainDataGrid.CurrentColumn.Header.ToString();//获取单元格表头名字(列名)
        //    string SqlStr = String.Format("SELECT * FROM(SELECT * FROM 联通进线 WHERE {0}='{1}' " +
        //        "UNION SELECT * FROM 电信进线 WHERE {2}='{3}' " +
        //        "UNION SELECT * FROM 铁通进线 WHERE {4}='{5}')", HeaderName, CellValue, HeaderName, CellValue, HeaderName, CellValue);
        //    //MessageBox.Show(ColumnIndex+" "+ HeaderName + " "+ CellValue+" "+ SqlStr);
        //    DataGrid DetailsDataGrid = e.DetailsElement as DataGrid;
        //    DataSet DS = GetDataSet(SqlStr, "DetailsDataTable");
        //    if (!IfExitData(DS,0))
        //    {
        //       // MainDataGrid.SelectedIndex = -1;//
        //        row.DetailsVisibility = Visibility.Collapsed;
        //        return;
        //    }
        //    DetailsDataGrid.ItemsSource = DS.Tables["DetailsDataTable"].DefaultView;
        //}
        private void YuYueDataGrid_RowDetailsVisibilityChanged_1(object sender, DataGridRowDetailsEventArgs e)
        {
            DataGrid MainDataGrid = sender as DataGrid;//主表
            DataGrid DetailsDataGrid = e.DetailsElement as DataGrid;//子表
            //MessageBox.Show(YuYueDataGrid.SelectedIndex.ToString());
            DataGridRow row = (DataGridRow)MainDataGrid.ItemContainerGenerator.ContainerFromIndex(YuYueDataGrid.SelectedIndex);//用于显示,收缩子表
            //DataGrid DDG = FindVisualChildByName<DataGrid>(row, "DetailsDataGrid") as DataGrid;//从表
            var cell = MainDataGrid.CurrentCell;
            int ColumnIndex = cell.Column.DisplayIndex;//获取单元格表头(列)索引.
            DataRowView SelectedRow = (DataRowView)YuYueDataGrid.SelectedItem;
            string CellValue = SelectedRow.Row[ColumnIndex].ToString();//
            /* 
             * cell.Item[cell.Column.];// 获取选中的当前单元格的值
             * 第3列以后不进行详细查询因而也不应显示 详细行的子表,但是主表的行这时应为被选状态,被选单元格应可编辑
             * 如果被选单元格为空值也不进行数据库详细查询,也不显示详细行的子表,但是主表的行这时应为被选状态,
             * 被选单元格应可编辑
             */
            //if (ColumnIndex > 3 || string.IsNullOrEmpty(CellValue))
            //{
            //    //MainDataGrid.SelectedIndex =-1;//这样设置成了无选择状态了,不符合要求
            //    row.DetailsVisibility = Visibility.Collapsed;
            //    //row.DetailsVisibility = row.DetailsVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
            //    return;
            //}

            string HeaderName = MainDataGrid.CurrentColumn.Header.ToString();//获取单元格表头名字(列名)
            string SqlStr = String.Format("SELECT * FROM(SELECT * FROM 联通进线 WHERE {0}='{1}' " +
                "UNION SELECT * FROM 电信进线 WHERE {2}='{3}' " +
                "UNION SELECT * FROM 铁通进线 WHERE {4}='{5}')", HeaderName, CellValue, HeaderName, CellValue, HeaderName, CellValue);
            //MessageBox.Show(ColumnIndex+" "+ HeaderName + " "+ CellValue+" "+ SqlStr);
            
            DataSet DS = GetDataSet(SqlStr, "DetailsDataTable");
            //if (!IfExitData(DS, 0))
            //{
            //    // MainDataGrid.SelectedIndex = -1;//
            //    //row.DetailsVisibility = row.DetailsVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
            //    row.DetailsVisibility = Visibility.Collapsed;
            //    return;
            //}
            DetailsDataGrid.ItemsSource = DS.Tables["DetailsDataTable"].DefaultView;
        }

        /// <summary>
		/// 检查一个DataSet 里面是否含有数据
		/// </summary>
		/// <param name="ds">要检测的DataSet</param>
		/// <param name="tableIndex">DataSet里Table的索引</param>
		/// <returns>True: 里面有数据。 False:里面没有数据</returns>
		public static bool IfExitData(DataSet ds, int tableIndex)
        {
            if (ds != null && ds.Tables[tableIndex].Rows.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>    
        /// 查找主表被点击的行明细中嵌套的控件名称,既子表名称.    
        /// </summary>    
        /// <typeparam name="T"></typeparam>    
        /// <param name="parent"></param>    
        /// <param name="name"></param>    
        /// <returns></returns>    
        public T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject
        {
            if (parent != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
                {
                    var child = VisualTreeHelper.GetChild(parent, i) as DependencyObject;
                    string controlName = child.GetValue(Control.NameProperty) as string;
                    if (controlName == name)
                    {
                        return child as T;
                    }
                    else
                    {
                        T result = FindVisualChildByName<T>(child, name);
                        if (result != null)
                        return result;
                    }
                }
            }
            return null;
        }
    }
}
tekcai.com 2018-04-19
  • 打赏
  • 举报
回复
<Window x:Class="YZTelApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:YZTelApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" >
    <Grid>
      <!--主从表-->
        <DataGrid Name="YuYueDataGrid" ItemsSource="{Binding}" AutoGenerateColumns="False" ColumnWidth="*" RowDetailsVisibilityChanged="YuYueDataGrid_RowDetailsVisibilityChanged_1">
            <DataGrid.Columns>
                <DataGridTextColumn Header="房号" Binding="{Binding 房号}" CanUserResize="False" Width="Auto"/>
                <DataGridTextColumn Header="电话号码" Binding="{Binding 电话号码}" CanUserResize="False" Width="Auto"/>
                <DataGridTextColumn Header="进线序号" Binding="{Binding 进线序号}" CanUserResize="False" Width="Auto"/>
                <DataGridTextColumn Header="出线位置" Binding="{Binding 出线位置}" CanUserResize="False" Width="Auto"/>
                <DataGridTextColumn Header="运营商" Binding="{Binding 运营商}" CanUserResize="False" Width="Auto"/>
                <DataGridTextColumn Header="安装日期" Binding="{Binding 安装日期}" CanUserResize="False" Width="Auto"/>
                <DataGridTextColumn Header="备注" Binding="{Binding 备注}"  />
            </DataGrid.Columns>
            <DataGrid.RowDetailsTemplate>
              <DataTemplate>
                    <!--从表-->
                <DataGrid Name="DetailsDataGrid" IsReadOnly="True" AutoGenerateColumns="False" Margin="15,8,8,8"  Background="Green" Width="399">
                  <DataGrid.Columns>
                      <DataGridTextColumn Header="房号" Binding="{Binding 房号}" Width="Auto"/>
                      <DataGridTextColumn Header="电话号码" Binding="{Binding 电话号码}" Width="Auto"/>
                      <DataGridTextColumn Header="进线序号" Binding="{Binding 进线序号}" Width="Auto"/>
                      <DataGridTextColumn Header="出线位置" Binding="{Binding 出线位置}" Width="Auto"/>
                      <DataGridTextColumn Header="运营商" Binding="{Binding 运营商}" Width="Auto"/>
                      <DataGridTextColumn Header="安装日期" Binding="{Binding 安装日期}" Width="Auto"/>
                  </DataGrid.Columns>
                </DataGrid>
              </DataTemplate>
            </DataGrid.RowDetailsTemplate>
        </DataGrid>
    </Grid>
</Window>
tekcai.com 2018-04-19
  • 打赏
  • 举报
回复
this.dataGridTest.RowDetailsVisibilityChanged += new EventHandler<DataGridRowDetailsEventArgs>(dataGrid1_RowDetailsVisibilityChanged); 添加从表
senler 2018-04-18
  • 打赏
  • 举报
回复
<DataGrid Name="DgMain" Grid.Row="2" ItemsSource="{Binding QueryMainList}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="姓名" Binding="{Binding UserName}"/>
            </DataGrid.Columns>
            <DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <DataGrid Name="DgSub" ItemsSource="{Binding QuerySubList}">
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="科目" Binding="{Binding subject}"/>
                            <DataGridTextColumn Header="成绩" Binding="{Binding Score}"/>
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
               </DataGrid.RowDetailsTemplate>
        </DataGrid>
引用 1 楼 techcai 的回复:
<Window x:Class="WpfDetailsApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfDetailsApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        
        <DataGrid Name="dataGridTest" ItemsSource="{Binding}">
            <DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <DataGrid Name="innerGrid"></DataGrid>
                </DataTemplate>
            </DataGrid.RowDetailsTemplate>
        </DataGrid>

    </Grid>
</Window>
using System;
using System.ComponentModel;
using System.Data;
using System.Windows;
using System.Windows.Controls;

namespace WpfDetailsApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        DataTable dt = new DataTable();
        public MainWindow()
        {
            InitializeComponent();
            dt.DefaultView.AllowNew = false;
            dt.Columns.Add("Num1", typeof(string));
            dt.Columns.Add("Num2", typeof(string));
            dt.Rows.Add("100", "200");
            dt.Rows.Add("300", "400");
            this.dataGridTest.DataContext = dt;
            this.dataGridTest.RowDetailsVisibilityChanged += new EventHandler<DataGridRowDetailsEventArgs>(dataGrid1_RowDetailsVisibilityChanged);

        }
        void dataGrid1_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
        {
            DataGrid innerDataGrid = e.DetailsElement as DataGrid;
            innerDataGrid.ItemsSource = ((IListSource)dt).GetList();
        }
    }
}

我需要用到mvvm模式的,
<DataGrid Name="DgMain" Grid.Row="2" ItemsSource="{Binding QueryMainList}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="姓名" Binding="{Binding UserName}"/>
            </DataGrid.Columns>
            <DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <DataGrid Name="DgSub" ItemsSource="{Binding QuerySubList}">
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="科目" Binding="{Binding subject}"/>
                            <DataGridTextColumn Header="成绩" Binding="{Binding Score}"/>
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
               </DataGrid.RowDetailsTemplate>
        </DataGrid>
我这个QuerySubList绑定不到数据,其实他是有数据的
tekcai.com 2018-04-18
  • 打赏
  • 举报
回复
<Window x:Class="WpfDetailsApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfDetailsApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        
        <DataGrid Name="dataGridTest" ItemsSource="{Binding}">
            <DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <DataGrid Name="innerGrid"></DataGrid>
                </DataTemplate>
            </DataGrid.RowDetailsTemplate>
        </DataGrid>

    </Grid>
</Window>
using System;
using System.ComponentModel;
using System.Data;
using System.Windows;
using System.Windows.Controls;

namespace WpfDetailsApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        DataTable dt = new DataTable();
        public MainWindow()
        {
            InitializeComponent();
            dt.DefaultView.AllowNew = false;
            dt.Columns.Add("Num1", typeof(string));
            dt.Columns.Add("Num2", typeof(string));
            dt.Rows.Add("100", "200");
            dt.Rows.Add("300", "400");
            this.dataGridTest.DataContext = dt;
            this.dataGridTest.RowDetailsVisibilityChanged += new EventHandler<DataGridRowDetailsEventArgs>(dataGrid1_RowDetailsVisibilityChanged);

        }
        void dataGrid1_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
        {
            DataGrid innerDataGrid = e.DetailsElement as DataGrid;
            innerDataGrid.ItemsSource = ((IListSource)dt).GetList();
        }
    }
}

8,735

社区成员

发帖
与我相关
我的任务
社区描述
WPF/Silverlight相关讨论
社区管理员
  • WPF/Silverlight社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧