Добавление записи и обновление пользовательского интерфейса - Шаблон MVVM - DataGrid в качестве Master, Другие элементы управления в качестве Detail - PullRequest
0 голосов
/ 04 января 2011

У меня есть основной список в DataGrid, который отображает все «мониторы» - думайте о них как об аудитах (для контекста).В основном, когда пользователь щелкает строку в DataGrid, все текстовые поля, поля со списками, флажки и датчики все отображают значения, и пользователь может редактировать их там, и это прекрасно отражается в DataGrid.об использовании одних и тех же TextBoxes, ComboBoxes, CheckBoxes и DatePickers для добавления новой записи?

<Monitor.VB>
Public Class Monitor
    Public Property MID As Integer
    Public Property FileNumber As String
    Public Property FiscalYear As Nullable(Of Integer)
    Public Property Monitor As String
    Public Property Type As String
    Public Property MDate As Date
    Public Property Performed As Boolean
    Public Property Completed As Boolean
    Public Property Comments As String
End Class

<Monitors.VB>
Imports System.Collections.ObjectModel
Imports System.Data

Public Class Monitors
    Inherits ObservableCollection(Of Monitor)

    Public Shared Function LoadMonitors(ByVal monitorDT As DataTable) As Monitors

        Dim monitorCollection As New Monitors

        For Each row As DataRow In monitorDT.Rows
            Dim newMonitor As New Monitor
            Dim MID As Integer = row.Item("MID")
            Dim FileNumber As String = row.Item("FileNumber")
            Dim FiscalYear As Nullable(Of Integer) = IIf(IsDBNull(row.Item("FiscalYear")), Nothing, row.Item("FiscalYear"))
            Dim Monitor As String = row.Item("Monitor")
            Dim Type As String = row.Item("Type")
            Dim MDate As Date = row.Item("MDate")
            Dim Performed As Boolean = row.Item("Performed")
            Dim Completed As Boolean = row.Item("Completed")
            Dim Comments As String = row.Item("Comments")

            newMonitor.MID = MID
            newMonitor.FileNumber = FileNumber
            newMonitor.FiscalYear = FiscalYear
            newMonitor.Monitor = Monitor
            newMonitor.Type = Type
            newMonitor.MDate = MDate
            newMonitor.Performed = Performed
            newMonitor.Completed = Completed
            newMonitor.Comments = Comments

            monitorCollection.Add(newMonitor)
        Next
        Return monitorCollection
    End Function

End Class

<MonitorViewModel.VB>
Imports System.Data
Imports System.ComponentModel

Public Class MonitorViewModel
    Inherits ViewModelBase

    Private _objMonitor As Monitor
    Private _monitors As Monitors
    Dim _selectedMonitor As Monitor

    Private monitorsView As ICollectionView

    Public Property Selection() As Monitor
        Get
            Return _selectedMonitor
        End Get
        Set(ByVal value As Monitor)
            If value Is _selectedMonitor Then
                Return
            End If
            _selectedMonitor = value
            Dim comments As String
            MyBase.OnPropertyChanged("Selection")
            comments = IIf(IsNothing(_selectedMonitor), String.Empty, _selectedMonitor.Comments)
        End Set
    End Property

    Public Property Monitors As Monitors
        Get
            Return _monitors
        End Get
        Set(ByVal value As Monitors)
            Me._monitors = value
            OnPropertyChanged("Monitors")
        End Set
    End Property

    Public Property MonitorModel() As Monitor
        Get
            Return _objMonitor
        End Get
        Set(ByVal Value As Monitor)
            _objMonitor = Value
            MyBase.OnPropertyChanged("Monitor")
        End Set
    End Property

    Public Property MID() As Integer
        Get
            Return _objMonitor.MID
        End Get
        Set(ByVal Value As Integer)
            _objMonitor.MID = Value
            MyBase.OnPropertyChanged("MID")
        End Set
    End Property

    Public Property FileNumber() As String
        Get
            Return _objMonitor.FileNumber
        End Get
        Set(ByVal Value As String)
            _objMonitor.FileNumber = Value
            MyBase.OnPropertyChanged("FileNumber")
        End Set
    End Property

    Public Property FiscalYear() As Integer
        Get
            Return _objMonitor.FiscalYear
        End Get
        Set(ByVal Value As Integer)
            _objMonitor.FiscalYear = Value
            MyBase.OnPropertyChanged("FiscalYear")
        End Set
    End Property

    Public Property Monitor() As String
        Get
            Return _objMonitor.Monitor
        End Get
        Set(ByVal Value As String)
            _objMonitor.Monitor = Value
            MyBase.OnPropertyChanged("Monitor")
        End Set
    End Property

    Public Property Type() As String
        Get
            Return _objMonitor.Type
        End Get
        Set(ByVal Value As String)
            _objMonitor.Type = Value
            MyBase.OnPropertyChanged("Type")
        End Set
    End Property

    Public Property MDate() As Date
        Get
            Return _objMonitor.MDate
        End Get
        Set(ByVal Value As Date)
            _objMonitor.MDate = Value
            MyBase.OnPropertyChanged("MDate")
        End Set
    End Property

    Public Property Performed() As Boolean
        Get
            Return _objMonitor.Performed
        End Get
        Set(ByVal Value As Boolean)
            _objMonitor.Performed = Value
            MyBase.OnPropertyChanged("Performed")
        End Set
    End Property

    Public Property Completed() As Boolean
        Get
            Return _objMonitor.Completed
        End Get
        Set(ByVal Value As Boolean)
            _objMonitor.Completed = Value
            MyBase.OnPropertyChanged("Completed")
        End Set
    End Property

    Public Property Comments() As String
        Get
            Return _objMonitor.Comments
        End Get
        Set(ByVal Value As String)
            _objMonitor.Comments = Value
            MyBase.OnPropertyChanged("Comments")
        End Set
    End Property

    Public Sub New(ByVal monitorDT As DataTable)
        Me._monitors = Monitors.LoadMonitors(monitorDT)
        Me.monitorsView = CollectionViewSource.GetDefaultView(Me._monitors)
    End Sub

    Public Sub New(ByVal monitorCollection As Monitors)
        Me._monitors = monitorCollection
        Me.monitorsView = CollectionViewSource.GetDefaultView(Me._monitors)
    End Sub

    Public Sub New()
    End Sub

#Region "Commanding"
    Private _cmdAddCommand As ICommand
    Private _cmdRemoveCommand As ICommand
    Private _cmdSaveCommand As ICommand

    Public ReadOnly Property AddCommand() As ICommand
        Get
            If _cmdAddCommand Is Nothing Then
                _cmdAddCommand = New RelayCommand(AddressOf AddExecute, AddressOf CanAddExecute)
            End If
            Return _cmdAddCommand
        End Get
    End Property

    Public ReadOnly Property RemoveCommand() As ICommand
        Get
            If _cmdRemoveCommand Is Nothing Then
                _cmdRemoveCommand = New RelayCommand(AddressOf Remove, AddressOf CanRemove)
            End If
            Return _cmdRemoveCommand
        End Get
    End Property

    Public ReadOnly Property SaveCommand() As ICommand
        Get
            If _cmdSaveCommand Is Nothing Then
                _cmdSaveCommand = New RelayCommand(AddressOf Save, AddressOf CanSave)
            End If
            Return _cmdSaveCommand
        End Get
    End Property

    Private Function CanAddExecute(ByVal param As Object) As Boolean
        Return True
    End Function

    Private Sub AddExecute(ByVal param As Object)
        Dim monitorLCV As ListCollectionView = CType(Me.monitorsView, ListCollectionView)
        monitorLCV.AddNew()
        monitorLCV.CommitNew()
    End Sub

    Private Function CanRemove(ByVal param As Object) As Boolean
        Return Me.Selection IsNot Nothing
    End Function

    Private Sub Remove(ByVal param As Object)
        Me.Monitors.Remove(Me.Selection)
    End Sub

    Private Function CanSave(ByVal param As Object) As Boolean
        Return True
    End Function

    Private Sub Save(ByVal param As Object)
        MsgBox("Save")
    End Sub
#End Region
End Class


<ViewModelBase.VB>
Imports System.ComponentModel

Public Class ViewModelBase

    Implements INotifyPropertyChanged

    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    Protected Sub OnPropertyChanged(ByVal strPropertyName As String)
        If Me.PropertyChangedEvent IsNot Nothing Then
            RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(strPropertyName))
        End If
    End Sub

End Class

<View>
<TabItem Header="Monitors" Name="ui_tcpMonitors">
                <TabItem.Resources>
                    <CollectionViewSource x:Key="MonitorViewSource" d:DesignSource="{d:DesignInstance my:Monitor, CreateList=True}" />
                </TabItem.Resources>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Text="Monitors" 
                               Style="{StaticResource GreenTextBlock}" FontSize="16"
                               Foreground="#FF7EA740" />
                    <TextBlock Grid.Row="1" Grid.Column="0" Text="Date Performed" Style="{StaticResource GreenTextBlock}"/>
                    <TextBlock Grid.Row="2" Grid.Column="0" Text="Monitor Type" Style="{StaticResource GreenTextBlock}"/>
                    <TextBlock Grid.Row="3" Grid.Column="0" Text="Monitor Site" Style="{StaticResource GreenTextBlock}"/>
                    <TextBlock Grid.Row="4" Grid.Column="0" Text="Fiscal Year" Style="{StaticResource GreenTextBlock}"/>
                    <TextBlock Grid.Row="1" Grid.Column="2" Text="Comments" Style="{StaticResource GreenTextBlock}"/>

                    <DatePicker Grid.Row="1" Grid.Column="1" Name="ui_dtpMonitorDatePerformed" Margin="5,2,5,2"
                                SelectedDate="{Binding Path=Selection.MDate}"
                                 SelectedDateFormat="Long"/>
                    <ComboBox Grid.Row="2" Grid.Column="1" Name="ui_cmbMonitorType" Margin="5,2,5,2"
                          SelectedItem="{Binding Path=Selection.Monitor}"/>

                    <ComboBox Grid.Row="3" Grid.Column="1" Name="ui_cmbMonitorSite" Margin="5,2,5,2"
                              SelectedValue="{Binding Path=Selection.Type}"/>

                    <ComboBox Grid.Row="4" Grid.Column="1" Name="ui_cmbMonitorFiscalYear" Margin="5,2,5,2"
                          ItemsSource="{Binding Path=FundingYear}"
                          SelectedItem="{Binding Path=Selection.FiscalYear}"/>
                    <TextBox Grid.Row="1" Grid.Column="3" Name="ui_txtMonitorComments" 
                             Style="{StaticResource OverallTextBox}" 
                             Text="{Binding Path=Selection.Comments}"
                             TextWrapping="Wrap" MaxHeight="100"
                             AcceptsReturn="True"
                             Grid.RowSpan="3"
                             MaxLength="250">
                    </TextBox>

                    <StackPanel Grid.Row="4" Grid.Column="3" Orientation="Horizontal">
                        <CheckBox Name="ui_chkMonitorPerformed" Content="Performed" Margin="5,2,5,2"
                                  IsChecked="{Binding Path=Selection.Performed}"/>
                        <CheckBox Name="ui_chkMonitorCompleted" Content="Completed" Margin="5,2,5,2" IsEnabled="False"
                                  IsChecked="{Binding Path=Selection.Completed}"/>
                    </StackPanel>
                    <Grid Grid.Row="5" Grid.Column="3">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Button Grid.Column="0" Content="Add" Name="ui_btnMonitorAdd" Margin="5"/>
                        <Button Grid.Column="1" Content="Remove" Name="ui_btnMonitorRemove" Margin="5" Command="{Binding RemoveCommand}"/>
                        <Button Grid.Column="2" Content="Clear" Name="ui_btnMonitorClear" Margin="5"/>
                    </Grid>
                    <DataGrid Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="4" Name="ui_dtgMonitors"
                      ItemsSource="{Binding Path=Monitors, Mode=TwoWay}" SelectedItem="{Binding Path=Selection, Mode=TwoWay}"
                      HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White"
                      SelectionMode="Single" Margin="2,5" IsReadOnly="True" CanUserAddRows="False" 
                      CanUserReorderColumns="False" CanUserResizeRows="False"
                      GridLinesVisibility="None" HorizontalScrollBarVisibility="Hidden"
                      ColumnHeaderStyle="{StaticResource GreenTea}" HeadersVisibility="Column" 
                      BorderThickness="2" BorderBrush="LightGray" CellStyle="{StaticResource NonSelectableDataGridCellStyle}"
                      SelectionUnit="FullRow" HorizontalContentAlignment="Stretch" AutoGenerateColumns="False">
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Fiscal Year" Binding="{Binding FiscalYear}" Width="Auto"/>
                            <DataGridTextColumn Header="Monitor" Binding="{Binding Monitor}" Width="Auto"/>
                            <DataGridTextColumn Header="Type" Binding="{Binding Type}" Width="Auto"/>
                            <DataGridTextColumn Header="Date" Binding="{Binding MDate, StringFormat={}{0:MMMM dd yyyy}}" Width="Auto"/>
                            <DataGridTextColumn Header="Performed" Binding="{Binding Performed}" Width="Auto"/>
                            <DataGridTextColumn Header="Completed" Binding="{Binding Completed}" Width="Auto"/>
                            <DataGridTextColumn Header="Comments" Binding="{Binding Comments}" Width="*"/>
                        </DataGrid.Columns>
                    </DataGrid>
                </Grid>
            </TabItem>

Ответы [ 2 ]

0 голосов
/ 04 января 2011
0 голосов
/ 04 января 2011

Одним из способов является использование DataBinding в вашем DataGrid;затем шаблон каждого столбца DataGrid в XAML.Затем добавление нового элемента в вашем ObservableCollection<T> будет распространяться на DataGrid с использованием шаблонных столбцов.

Пример ниже о том, как шаблонировать столбцы ...

<dg:DataGrid 
            AutoGenerateColumns="False" 
            ItemsSource="{Binding Connections, Mode=Default}"
            SelectedItem="{Binding Connection}">
            <dg:DataGrid.Columns>
                <dg:DataGridTextColumn Header="Display" Binding="{Binding DisplayName}"/>
                <dg:DataGridTextColumn Header="Host" Binding="{Binding HostName}"/>
                <dg:DataGridTextColumn Header="Database" Binding="{Binding Database}"/>
                <dg:DataGridTextColumn Header="Username" Binding="{Binding Username}"/>
                <dg:DataGridTextColumn Header="Password" Binding="{Binding Password}"/>
                <dg:DataGridTemplateColumn  >
                    <dg:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <Button Grid.Column="0" Margin="0,0,4,0"
                                    Width="75"
                                    Content="Validate"
                                    Command="{Binding DataContext.ValidateConnectionCommand, RelativeSource={RelativeSource AncestorType={x:Type dg:DataGrid}, Mode=FindAncestor}}" CommandParameter="{Binding}">
                                </Button>
                                <Button Grid.Column="1"
                                    Width="75"
                                    Content="Delete"
                                    Command="{Binding DataContext.DeleteConnectionCommand, RelativeSource={RelativeSource AncestorType={x:Type dg:DataGrid}, Mode=FindAncestor}}" CommandParameter="{Binding}">
                                </Button>
                            </Grid>
                        </DataTemplate>
                    </dg:DataGridTemplateColumn.CellTemplate>
                </dg:DataGridTemplateColumn>
            </dg:DataGrid.Columns>
        </dg:DataGrid>

Свойство Connections представляет собой ObservableCollection<T>, в котором будет отображаться уведомление об изменении после добавления нового элемента.в коллекции;тем самым обновляя интерфейс.Таким образом, для вашего сценария (в C #, поскольку я не знаком с VB), вы должны связать свойство ItemsSource DataGrid со свойством Monitors в ViewModel ...

ObservableCollection<Monitor> monitors = new ObservableCollection<Monitor>();
... 
public ObservableCollection<Monitor> Monitors
{
   get
   {
        return monitors;
   }
} 
...
...