Benutzer mit den meisten Antworten
datagrid binding two way

Frage
-
I have a wpf datagrid with a checkboxcolumn. In all rows only exactly one row should have this column checked (like a radiobutton)
With NotifyOnTargetUpdated=True and adding a suitable handler, I get all clicks in these checkboxes. Works fine and I do the above "Radio button" Task on may rowdata, derived from (ObservableCollection). But I find no way to instantanously update the datagrid view, showing many checks instead. Binding from source to target doesnt work.
Tried sucessless with INotifyPropertyChange interface and direct calling UpdateTarget. Can u post an very simple example solving my Problem.
Antworten
-
Hi,
nachfolgend mal eine MVVM-Demo zur Lösung Deines Problems. Wichtig ist, dass das Datenobjekt die Änderung des Checked-Zustandes per NotifyPropertyChanged meldet und die Collection diese Änderung auch weitermeldet. Dadurch können die Zustände in den anderen Datenobjekten rückgesetzt werden. Als Collection eignet sich eine von ObservableCollection abgeleitete Collection, die die Änderungen "fängt" und weitermeldet, im Beispiel die TrulyObservableCollection.XAML:
<Window x:Class="Window33" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="Window33" Height="450" Width="800"> <Window.DataContext> <local:Window33VM/> </Window.DataContext> <Grid> <DataGrid ItemsSource="{Binding View}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="ID" Binding="{Binding ID}"/> <DataGridTextColumn Header="Info" Binding="{Binding Info}"/> <DataGridTemplateColumn Header="Checked"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox IsChecked="{Binding Path=Checked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window>
Datenklassen:
Imports System.Collections.Specialized Imports System.ComponentModel Imports System.Runtime.CompilerServices Public Class Window33VM Private col As New TrulyObservableCollection(Of Window33Data) Private cvs As New CollectionViewSource ''' <summary> ''' View to display the list of items ''' </summary> ''' <returns></returns> Public ReadOnly Property View As ICollectionView Get If cvs.Source Is Nothing Then col = GetData() cvs.Source = col AddHandler col.CollectionChanged, Sub(sender As Object, e As NotifyCollectionChangedEventArgs) Dim d = TryCast(e.NewItems(0), Window33Data) If d IsNot cvs.View.CurrentItem Then Exit Sub If e.Action = NotifyCollectionChangedAction.Replace AndAlso d.Checked Then For Each item In col If item IsNot d AndAlso item.Checked Then item.Checked = False Next End If End Sub End If Return cvs.View End Get End Property Private Function GetData() As TrulyObservableCollection(Of Window33Data) Dim col As New TrulyObservableCollection(Of Window33Data) For i = 1 To 10 col.Add(New Window33Data With {.ID = i, .Info = $"Data {i}"}) Next Return col End Function End Class Public Class Window33Data Implements INotifyPropertyChanged Public Property ID As Integer Public Property Info As String Private _checked As Boolean = False Public Property Checked As Boolean Get Return Me._checked End Get Set(value As Boolean) Me._checked = value OnPropChanged() End Set End Property Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged Private Sub OnPropChanged(<CallerMemberName> Optional propName As String = "") RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName)) End Sub End Class
--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 29. Mai 2019 06:00
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Donnerstag, 6. Juni 2019 12:57