Reputation: 2688
I have a datagrid who's ItemsSource is a strongly typed IEnumerable object
In this datagrid, I have a checkbox column, a price column, a part name column, and a 'total selling for' column.
On checking the checkbox I need to update the total selling for column with the value in the price column.
This part I have working, however, how can I get the checkbox to remain checked when this happens?
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
uncommenting _CB.IsChecked = True does nothing
Here's the XAML for this datagrid:
<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>
Upvotes: 0
Views: 1468
Reputation: 5944
Here is an example of how it is more the WPF way, hopefully this gets you in the right direction. It has been a long time since I touched Visual Basic so please mind some missed conventions by me.
The 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>
Code Behind (Window Class and Part Class):
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
Upvotes: 1
Reputation: 45096
Pretty sure what is happening is this Event is fired before the update (set). So when you refresh you are getting the prior value. Assign the value of the CheckBox to the Property before you call refresh.
Upvotes: 1