【问题标题】:Expand/Collapse a gridviewrow in mvvm在 mvvm 中展开/折叠 gridviewrow
【发布时间】:2013-12-09 09:43:32
【问题描述】:

我有一个数据网格。它绑定到患者的集合。

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

这是我的 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");
                    }
                }
            }
        }
    }
}

这是我的输出:

从上图中可以看出,我没有正确获取详细信息。

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

【问题讨论】:

    标签: c# wpf silverlight xaml mvvm


    【解决方案1】:

    这里有几个问题:

    1) 您在RowDetailsTemplate 中的DataGrid 不正确。您错过了 DataGrid.Columns 标记,这意味着您正在通过 XAML 设置 ItemsItemsSource,这会导致异常。

    2) 您正在将 ItemsSource 绑定到一个名为 ReportNames 的属性,WPF 期望它位于您的 Patient(每行的 DataContext)类中 - 毕竟您正在显示该行的详细信息。但是,从您的 ViewModel 代码来看,ReportNames 属性似乎不在 Patient 类中,而是在 MainWindowViewModel 类中。您需要将 ReportNames 属性移动到 Patient 类,或者您需要将 Binding 更改为不在 Patient 类中而是在 MainWindowViewModel 类中查找 ReportNames。因为,我不知道您将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>
    

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

    【讨论】:

    • 太棒了!你已经在几分钟内完成了。在过去的 6-7 个小时里,我一直在解决这个问题。感谢您再次解决我的问题。
    • 要查找绑定错误,请在调试模式下运行您的应用并检查输出窗口中是否存在任何 WPF 绑定错误。
    • 感谢您的建议。我会记住的。我只是想问一个问题。如何在上面的示例中使用 selectedItem 属性而不是 SelectedIndex,因为我想启用排序。
    • 在您的 ViewModel 上有一个属性,例如 public Patient SelectedPatient { get; set; } 并绑定到您的 View 中的 DataGrid.SelectedItem
    • 我尝试了上面评论中的代码,它工作正常。再次感谢您。
    【解决方案2】:

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

    <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>
    

    【讨论】:

    • 我的输出仍然没有任何变化。
    猜你喜欢
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 2013-06-06
    • 2012-05-30
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多