DataGrid.Refresh()上的Datagrid更新复选框IsChecked

时间:2012-03-20 19:59:44

标签: .net wpf vb.net datagrid wpfdatagrid

我有一个datagrid,其ItemsSource是一个强类型的IEnumerable对象

在此数据网格中,我有一个复选框列,一个价格列,一个零件名称列和一个“总销售额”列。

选中此复选框后,我需要使用价格列中的值更新列的总销售额。

这部分我已经工作了,但是,当发生这种情况时,如何让复选框保持检查状态?

Private Sub UpdateSellFor(sender As System.Object, e As System.Windows.RoutedEventArgs)
    Dim _CB As CheckBox = DirectCast(sender, CheckBox)
    Dim _ID As Integer = _CB.Tag
    Dim _PP = DirectCast(DG_PartsToSelect.CurrentItem, PartTyping).PartPrice
    If _CB.IsChecked Then
        DG_PartsToSelect.CurrentItem.PartSellingFor = DirectCast(DG_PartsToSelect.CurrentItem, PartTyping).PartPrice
        DG_PartsToSelect.Items.Refresh()
    Else

    End If
    '_CB.IsChecked = True
End Sub

取消注释_CB.IsChecked = True不执行任何操作

以下是此数据网格的XAML:

                <DataGrid IsReadOnly="True" AutoGenerateColumns="False" Grid.Column="1" HorizontalAlignment="Stretch" Margin="3" Name="DG_PartsToSelect" VerticalAlignment="Stretch">
                    <DataGrid.Columns>
                        <DataGridTextColumn Header="Part ID" Binding="{Binding PartID}" />
                        <DataGridTemplateColumn Header="Part Name">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding PartName}" Cursor="Hand" MouseDown="PartDetails" Tag="{Binding PartID}" ToolTip="Click to See the Part Details" />
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTextColumn Header="Selling For" Binding="{Binding PartPrice, StringFormat='{}{0:C}'}" />
                        <DataGridTemplateColumn Header="Part Options">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <Image Cursor="Hand" Height="22" Name="options" Tag="{Binding PartID}" MouseDown="PartOptions" Source="/v2Desktop;component/Images/Application.png" ToolTip="Select Part Options" />
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTemplateColumn Header="Sell This Part">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <CheckBox Name="SelectedPart" Tag="{Binding PartID}" ToolTip="Select This Part" Click="UpdateSellFor" />
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTextColumn Header="Total Selling For" Binding="{Binding PartSellingFor, StringFormat='{}{0:C}'}" />
                    </DataGrid.Columns>
                </DataGrid>

2 个答案:

答案 0 :(得分:1)

非常确定发生的事件是在更新(设置)之前触发此事件。因此,当您刷新时,您将获得先前的值。在调用refresh之前,将CheckBox的值分配给Property。

答案 1 :(得分:1)

这是一个如何更多WPF方式的例子,希望这能让你朝着正确的方向前进。 自从我触及Visual Basic以来已经有很长一段时间了,所以请介意一些我错过的惯例。

Xaml:

    <DataGrid AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="3" x:Name="DG_PartsToSelect" VerticalAlignment="Stretch" ItemsSource="{Binding}">
      <DataGrid.Columns>
        <DataGridTextColumn Header="ID" Binding="{Binding Path=ID}" IsReadOnly="True" />
        <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" IsReadOnly="True"/>
        <DataGridTemplateColumn Header="Selling For">
          <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
              <TextBlock Text="{Binding Path=SellingPrice, StringFormat='{}{0:C}', Mode=OneWay}"/>
            </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
          <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
              <TextBox Text="{Binding Path=SellingPrice, UpdateSourceTrigger=PropertyChanged}"/>
            </DataTemplate>
          </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Part Options">
          <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
              <Border Background="#88BBFF" Cursor="Hand" Height="22" ToolTip="Select Part Options" MouseUp="PartOptions_MouseUp"/><!--just for testing with no image-->
              <!--<Image Cursor="Hand" Height="22" Source="" ToolTip="Select Part Options" MouseDown="PartOptions_MouseDown"/>-->
            </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Sell This Part">
          <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
              <CheckBox Name="SelectedPart" IsChecked="{Binding Path=IsCalculated, UpdateSourceTrigger=PropertyChanged}" ToolTip="Select This Part"  />
            </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn IsReadOnly="True" Header="Total Selling For" Binding="{Binding Path=TotalSellingFor, StringFormat='{}{0:C}'}" />
      </DataGrid.Columns>
    </DataGrid>

代码背后(窗口类和零件类):

Imports System.ComponentModel
Imports System.Collections.ObjectModel

Class MainWindow

  Dim Parts As ObservableCollection(Of Part)

  Private Sub PartOptions_MouseUp(sender As System.Object, e As System.Windows.Input.MouseButtonEventArgs)
    If DG_PartsToSelect.SelectedItem Is Nothing Then
      Exit Sub
    End If
    Dim selectedPart = DirectCast(DG_PartsToSelect.SelectedItem, Part)
    MessageBox.Show(String.Format("The name = {0}", selectedPart.Name), String.Format("The id = {0}", selectedPart.ID), MessageBoxButton.OK, MessageBoxImage.Information)
  End Sub

  Public Sub New()
    InitializeComponent()
    Parts = New ObservableCollection(Of Part)
    Parts.Add(New Part(1, "test", 100D))
    Parts.Add(New Part(2, "Name here", 99.99D))
    Parts.Add(New Part(3, "What", 23.19D))
    DG_PartsToSelect.DataContext = Parts
  End Sub
End Class

Public Class Part : Implements INotifyPropertyChanged

  Private IDField As Integer
  Public Property ID() As Integer
    Get
      Return IDField
    End Get
    Set(ByVal value As Integer)
      IDField = value
      OnPropertyChanged("ID")
    End Set
  End Property

  Private NameField As String
  Public Property Name() As String
    Get
      Return NameField
    End Get
    Set(ByVal value As String)
      NameField = value
      OnPropertyChanged("Name")
    End Set
  End Property

  Private SellingPriceField As Decimal
  Public Property SellingPrice() As Decimal
    Get
      Return SellingPriceField
    End Get
    Set(ByVal value As Decimal)
      SellingPriceField = value
      OnPropertyChanged("SellingPrice")
      IsCalculatedField = False
      OnPropertyChanged("IsCalculated")
    End Set
  End Property

  Private IsCalculatedField As Boolean
  Public Property IsCalculated() As Boolean
    Get
      Return IsCalculatedField
    End Get
    Set(ByVal value As Boolean)
      If (IsCalculatedField And Not value) Then
        Exit Property
      End If
      IsCalculatedField = value
      UpdateTotalPrice()
    End Set
  End Property

  Private TotalSellingForField As Decimal
  Public Property TotalSellingFor() As Decimal
    Get
      Return TotalSellingForField
    End Get
    Set(ByVal value As Decimal)
      TotalSellingForField = value
    End Set
  End Property

  Public Event PropertyChanged As PropertyChangedEventHandler _
        Implements INotifyPropertyChanged.PropertyChanged

  Public Sub New(id As Integer, name As String, sellingPrice As Decimal)
    IDField = id
    NameField = name
    SellingPriceField = sellingPrice
  End Sub

  Sub UpdateTotalPrice()
    ''This will multiply the price of the SellingPriceValue times 2 and put it in the TotalSellingForField
    TotalSellingForField = SellingPriceField * 2
    OnPropertyChanged("TotalSellingFor")
  End Sub

  Sub OnPropertyChanged(propertyName As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
  End Sub

End Class