展开/折叠mvvm中的gridviewrow

时间:2013-12-09 09:43:32

标签: c# wpf silverlight xaml mvvm

我有一个数据网格。它与一组患者有关。

现在我想在选择更改时扩展它,以便我可以看到患者的详细信息。

这是我的xaml:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Patients}" 
          SelectedIndex="{Binding SelectedID}" RowDetailsVisibilityMode="VisibleWhenSelected"
          IsReadOnly="True" SelectionMode="Single" SelectionUnit="FullRow" >
    <DataGrid.Resources>
        <Style x:Key="VerticalCenter" TargetType="TextBlock">
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
        </Style>
        <Style x:Key="VerticalAndHorizontalCenter" TargetType="FrameworkElement" >
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="HorizontalAlignment" Value="Center"></Setter>
        </Style>
        <Style x:Key="VerticalAndHorizontalCenterTextBlock" TargetType="TextBlock"
               BasedOn="{StaticResource VerticalAndHorizontalCenter}"/>
        <Style x:Key="VerticalAndHorizontalCenterHeader" TargetType="{x:Type DataGridColumnHeader}" 
               BasedOn="{StaticResource VerticalAndHorizontalCenter}"/>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding PatientName}" Header="Patient Name" Width="25*" 
                            ElementStyle="{StaticResource VerticalCenter}"/>
        <DataGridTextColumn Binding="{Binding City}" Header="City" Width="15*" 
                            ElementStyle="{StaticResource VerticalAndHorizontalCenterTextBlock}" 
                            HeaderStyle="{StaticResource VerticalAndHorizontalCenterHeader}"/>
        <DataGridTextColumn Binding="{Binding Sex}" Header="Sex" Width="10*" 
                            ElementStyle="{StaticResource VerticalAndHorizontalCenterTextBlock}"
                            HeaderStyle="{StaticResource VerticalAndHorizontalCenterHeader}"/>
        <DataGridTextColumn Binding="{Binding Age}" Header="Age" Width="5*" 
                            ElementStyle="{StaticResource VerticalAndHorizontalCenterTextBlock}" 
                            HeaderStyle="{StaticResource VerticalAndHorizontalCenterHeader}"/>
        <DataGridTemplateColumn Header="Delete">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Image Source="Images/Delete.png" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>

    <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <DataGrid AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="{Binding ReportNames}">
                <DataGridTextColumn Binding="{Binding ReportNames}" Header="Report Name" />
                <!--<DataGridTextColumn Binding="{Binding DateOfReport}" Header="Date" />-->
                <DataGridTemplateColumn Header="Delete">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Image Source="Images/Delete.png" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid>
        </DataTemplate>    
    </DataGrid.RowDetailsTemplate>

</DataGrid>

这是我的ViewModel:

class MainWindowViewModel : INotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        using (Lab_Lite_Entities db = new Lab_Lite_Entities())
        {
            ReportNames = new List<string>();
        }
    }
    private IEnumerable<Patient> _patients;
    public IEnumerable<Patient> Patients
    {
        get
        {
            return _patients;
        }
        set
        {
            _patients = value;
            OnPropertyChanged("Patients");
        }
    }

    private List<string> _reportNames;
    public List<string> ReportNames
    {
        get
        {
            return _reportNames;
        }
        set
        {
            _reportNames = value;
            OnPropertyChanged("ReportNames");
        }
    }

    private int _selectedID;
    public int SelectedID
    {
        get
        {
            return _selectedID;
        }
        set
        {
            _selectedID = value;
            OnPropertyChanged("SelectedID");

            using (Lab_Lite_Entities db = new Lab_Lite_Entities())
            {
                if (SelectedID > -1)
                {

                    ReportNames.Clear();

                    if ((from p in db.Patients select p).Where(p => p.PatientID == SelectedID + 1).Select(p => p.Haemograms.Count()).FirstOrDefault() > 0)
                    {
                        ReportNames.Add("Haemogram Report");
                    }

                    if ((from p in db.Patients select p).Where(p => p.PatientID == SelectedID + 1).Select(p => p.UrineAnalysis.Count()).FirstOrDefault() > 0)
                    {
                        ReportNames.Add("Urine Analysis");
                    }

                    if ((from p in db.Patients select p).Where(p => p.PatientID == SelectedID + 1).Select(p => p.BloodChemistries.Count()).FirstOrDefault() > 0)
                    {
                        ReportNames.Add("Blood Chemistry");
                    }

                    if ((from p in db.Patients select p).Where(p => p.PatientID == SelectedID + 1).Select(p => p.WidalTests.Count()).FirstOrDefault() > 0)
                    {
                        ReportNames.Add("Widal Test");
                    }

                    if ((from p in db.Patients select p).Where(p => p.PatientID == SelectedID + 1).Select(p => p.SerologicalTests.Count()).FirstOrDefault() > 0)
                    {
                        ReportNames.Add("Serological Test");
                    }

                    if ((from p in db.Patients select p).Where(p => p.PatientID == SelectedID + 1).Select(p => p.DengueTests.Count()).FirstOrDefault() > 0)
                    {
                        ReportNames.Add("Dengue (Immunological Test)");
                    }

                    if ((from p in db.Patients select p).Where(p => p.PatientID == SelectedID + 1).Select(p => p.HIVTests.Count()).FirstOrDefault() > 0)
                    {
                        ReportNames.Add("HIV (Immunological Test)");
                    }

                    if ((from p in db.Patients select p).Where(p => p.PatientID == SelectedID + 1).Select(p => p.Troponin1Test.Count()).FirstOrDefault() > 0)
                    {
                        ReportNames.Add("Troponion-I Test");
                    }

                    if ((from p in db.Patients select p).Where(p => p.PatientID == SelectedID + 1).Select(p => p.UrinaryPregnancyCardTests.Count()).FirstOrDefault() > 0)
                    {
                        ReportNames.Add("Pregnancy Card Test");
                    }

                    if ((from p in db.Patients select p).Where(p => p.PatientID == SelectedID + 1).Select(p => p.HepatitisBSurfaceAntigenTests.Count()).FirstOrDefault() > 0)
                    {
                        ReportNames.Add("HBS Antigen Test");
                    }
                }
            }
        }
    }
}

这是我的输出:

enter image description here

正如您从上图所示,我无法正确获取详细信息。

我怀疑我在内部数据网格中绑定时遇到了一些错误,但我不知道如何纠正它。请给我一些解决方案。

2 个答案:

答案 0 :(得分:2)

这里有几个问题:

1)DataGrid中的RowDetailsTemplate不正确。您错过了DataGrid.Columns代码,这意味着您要通过XAML同时设置ItemsItemsSource,这会导致异常。

2)您正在将ItemsSource绑定到名为ReportNames的属性,WPF希望它在您的Patient(每行的DataContext)类中 - 在您显示该行的详细信息之后。但是,从您的ViewModel代码中,ReportNames属性似乎不在Patient类中,而是在MainWindowViewModel类中。您需要将ReportNames属性移至Patient课程,或者您需要将Binding更改为ReportNames课程中的Patient但{{1} } .class。既然如此,我不知道您MainWindowViewModel ReportNames中保留MainWindowViewModel的理由,我选择更新Binding

将RowDetailTemplate更改为:

<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <DataGrid AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="{Binding DataContext.ReportNames, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding}" Header="Report Name" />
                <DataGridTemplateColumn Header="Delete">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Image Source="Images/Delete.png" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </DataTemplate>
</DataGrid.RowDetailsTemplate>

请注意,我假设您在DataGrid中拥有主Window,这就是我在Winwow绑定中使用AncestorType作为RelativeSource的原因。您可能希望根据您的代码进行更改。

答案 1 :(得分:0)

您只需将行详细信息网格视图的高度设置为自动:

<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <DataGrid AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="{Binding ReportNames}" Height="Auto">
            <DataGridTextColumn Binding="{Binding ReportNames}" Header="Report Name" />
            <!--<DataGridTextColumn Binding="{Binding DateOfReport}" Header="Date" />-->
            <DataGridTemplateColumn Header="Delete">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Image Source="Images/Delete.png" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid>
    </DataTemplate>    
</DataGrid.RowDetailsTemplate>