Quantcast
Viewing all articles
Browse latest Browse all 18858

wpf datagrid - binding question about code behind

Even though the datagrid performs like it should, I'm wondering if my code is not optimal.  When I put breakpoints in the code to follow what it does, I see some repetition that I'm not sure should happen.  It appears to be a very expensive repetition as far as system resources.

Sample data:

Image may be NSFW.
Clik here to view.

Xaml:

<Window x:Class="DentalDB.PartBBilling_Window"
    x:Name="Window"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Part B Billing" Height="300" Width="805" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" Background="#FF336B7B"><Grid Width="743" Height="259"><Grid.RowDefinitions><RowDefinition Height="139*" /><RowDefinition Height="122*" /></Grid.RowDefinitions><DataGrid ItemsSource="{Binding PartB}" AutoGenerateColumns="False" Height="237" HorizontalAlignment="Left" Margin="12,12,0,0" Name="dgPartBBilling" 
                  VerticalAlignment="Top" Width="731" AlternationCount="2" AlternatingRowBackground="LightBlue" Grid.RowSpan="2"><DataGrid.Columns><DataGridTemplateColumn x:Name="dPartBBilling_Date" Width="100" Header="Billing Date"><DataGridTemplateColumn.CellTemplate><DataTemplate><TextBlock Text="{Binding Path=PartBBilling_Date, StringFormat=\{0:d\}}" Width="75"/></DataTemplate></DataGridTemplateColumn.CellTemplate><DataGridTemplateColumn.CellEditingTemplate><DataTemplate><Grid FocusManager.FocusedElement="{Binding ElementName= dPartBBilling_Date}"  ><DatePicker x:Name="dPartBBilling_Date" 
                                    SelectedDate="{Binding Path=PartBBilling_Date}" /> </Grid></DataTemplate></DataGridTemplateColumn.CellEditingTemplate></DataGridTemplateColumn><DataGridTemplateColumn Header="CPT Code" Width="75"><DataGridTemplateColumn.CellTemplate><DataTemplate><ComboBox ItemsSource="{Binding PartBCombo, 
                                        RelativeSource={RelativeSource AncestorType=Window}}" 
                                        DisplayMemberPath="PartBLookup_CPTCode" 
                                        SelectedValuePath="PartBLookup_ProcedureDescription"  
                                        SelectedValue="{Binding PartBBilling_ProcedureName, UpdateSourceTrigger=PropertyChanged}"
                                        SelectedItem="{Binding PartBBilling_CPT}"/></DataTemplate></DataGridTemplateColumn.CellTemplate></DataGridTemplateColumn><DataGridTextColumn Header="Procedure Name" Width="250" Binding="{Binding PartBBilling_ProcedureName}" IsReadOnly="True"/><DataGridTextColumn Header="Tooth #" Width="120" Binding="{Binding PartBBilling_Tooth}" /><DataGridTextColumn Header="Quantity" Width="75" Binding="{Binding PartBBilling_Quantity}" /><DataGridTextColumn Header="Total" Width="75" Binding="{Binding PartBBilling_Total, StringFormat=N2}" IsReadOnly="True"/></DataGrid.Columns></DataGrid></Grid></Window>

Code behind:

Imports System.Collections.ObjectModel
Imports System.ComponentModel

Namespace DentalDB

    Partial Public Class PartBBilling_Window
        Inherits Window
        Implements INotifyPropertyChanged

        Private Sub RaisePropertyChanged(prop As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(prop))
        End Sub

        Public Sub New()

            ' This call is required by the designer.
            InitializeComponent()

            ' Add any initialization after the InitializeComponent() call.

            'fill combobox with items
            If conn.State = ConnectionState.Closed Then
                conn.Open()
            End If

            cmd = New SqlCommand()
            cmd.Connection = conn

            cmd.CommandText = "SELECT CPT, ProcedureName FROM tlkpProcedures_PartB ORDER BY CPT"
            Dim Reader As SqlDataReader = cmd.ExecuteReader()

            PartBCombo = New List(Of PartBBilling_Combobox)

            If Reader.HasRows Then
                While Reader.Read()
                    PartBCombo.Add( _
                        New PartBBilling_Combobox() With { _
                            .PartBLookup_CPTCode = Reader("CPT").ToString,
                            .PartBLookup_ProcedureDescription = Reader("ProcedureName").ToString
                       })
                End While
            End If

            Reader.Close()
            conn.Close()


            'fill datagrid
            PartB = New List(Of PartBBilling)

            If conn.State = ConnectionState.Closed Then
                conn.Open()
            End If

            cmd = New SqlCommand()
            cmd.Connection = conn

            sSQL = "SELECT " & _"tblBilling_PartB.RW, " & _"tblBilling_PartB.BillingDate, " & _"tblBilling_PartB.CPT, " & _"ISNULL(tlkpProcedures_PartB.ProcedureName, '') AS ProcedureName, " & _"tblBilling_PartB.Tooth, " & _"tblBilling_PartB.Quantity, " & _"ISNULL(tlkpProcedures_PartB.BillingAmount * tblBilling_PartB.Quantity, '') AS Total, " & _"tblBilling_PartB.UniqueID " & _"FROM tblBilling_PartB " & _"LEFT JOIN tlkpProcedures_PartB ON tblBilling_PartB.CPT = tlkpProcedures_PartB.CPT " & _"WHERE RW = " & CInt(RW) & " " & _"ORDER BY tblBilling_PartB.BillingDate DESC"

            cmd.CommandText = sSQL

            Reader = cmd.ExecuteReader()

            If Reader.HasRows Then
                'bolCheckDate = False

                While Reader.Read()
                    PartB.Add( _
                        New PartBBilling() With { _
                            .PartBBilling_RW = Reader("RW").ToString,
                            .PartBBilling_Date = Reader("BillingDate"),
                            .PartBBilling_CPT = Reader("CPT").ToString,
                            .PartBBilling_ProcedureName = Reader("ProcedureName").ToString,
                            .PartBBilling_Tooth = Reader("Tooth").ToString,
                            .PartBBilling_Quantity = Reader("Quantity")
                       })
                End While
            End If

            conn.Close()

            DataContext = Me

        End Sub

        Public Property PartBCombo As List(Of PartBBilling_Combobox)
            Get
                Return _PartBCombo
            End Get
            Set(value As List(Of PartBBilling_Combobox))
                _PartBCombo = value
            End Set
        End Property
        Private _PartBCombo As List(Of PartBBilling_Combobox)

        Public Property PartB As List(Of PartBBilling)
            Get
                Return _PartB
            End Get
            Set(value As List(Of PartBBilling))
                _PartB = value
            End Set
        End Property
        Private _PartB As List(Of PartBBilling)

        Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

    End Class

End Namespace

Class for combobox items:

Imports System

Namespace DentalDB

    Public Class PartBBilling_Combobox

        Private _PartBLookup_CPTCode As String
        Public Property PartBLookup_CPTCode As String
            Get
                Return _PartBLookup_CPTCode
            End Get
            Set(value As String)
                _PartBLookup_CPTCode = value
            End Set
        End Property

        Private _PartBLookup_ProcedureDescription As String
        Public Property PartBLookup_ProcedureDescription As String
            Get
                Return _PartBLookup_ProcedureDescription
            End Get
            Set(value As String)
                _PartBLookup_ProcedureDescription = value
            End Set
        End Property

    End Class

End Namespace

The combobox class code above is executed 45 times, one for each item.  This is what I would expect.

Then it's executed multiple times again while,   I presume,   the datagrid is loading with data.  But I can't pinpoint down where this happens.  Using the sample data, for the first row "Bitewing-Single Film", this class will execute 55 times, 45 times to go thru the combo items, then another 10 times to get to "Bitewing-Single Film" which is the 10th item in the list (a breakpoint in the Get for the ProcedureName confirms this).

For the next row "Limited Oral Exam/Problem focused", the code will execute 56 times, 45 for each item in the combo, the 11 more times because "Limited Oral..." is the 11th item.

"Panoramic Film" is the 15th item.  Code is executed 45 + 15 times.

I think the combo is trying to match the CPT with the Procedure Name but this constant looping seems to be overkill.

Is this just its nature or is there something  that can be done to make this more streamlined?


Thanks.


Viewing all articles
Browse latest Browse all 18858

Trending Articles