WPF Datagrid with SelectedItem doesn't show updates to ViewModel property

89 Views Asked by At

I have a ReadOnly DataGrid in a WPF UserControl bound to a ViewModel (VM) and a SelectedItem bound to a Property of the VM. There are also two textboxes, one bound to a SelectedItem Property and one bound to a VM Property.

<UserControl
    x:Class="PhoneAssistant.WPF.Features.ServiceRequests.ServiceRequestsMainView"
    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:local="clr-namespace:PhoneAssistant.WPF.Features.ServiceRequests"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    d:DataContext="{d:DesignInstance Type=local:ServiceRequestsMainViewModel}"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid
            Grid.Row="0"
            Margin="16,20,0,15"
            d:Background="LightCoral">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto" />
                <ColumnDefinition Width="auto" />
            </Grid.ColumnDefinitions>
            <TextBox
                Grid.Column="0" Margin="0,0,5,0"
                Text="{Binding SelectedSR.BoundToSelected}" />
            <TextBox
                Grid.Column="1" Margin="0,0,5,0"
                Text="{Binding VmProperty}" />
        </Grid>
        <DataGrid
            Grid.Row="1" AutoGenerateColumns="False"
            IsReadOnly="true"
            ItemsSource="{Binding ServiceRequests}"
            SelectedItem="{Binding SelectedSR}"
            SelectionMode="Single"SelectionUnit="FullRow">
            <DataGrid.Columns>
                <DataGridTextColumn
                    Width="auto"
                    Binding="{Binding BoundToSelected}"
                    Header="BoundToSelected" />
                <DataGridTextColumn
                    Width="auto"
                    Binding="{Binding BoundToVMProperty}"
                    Header="BoundToVMProperty" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</UserControl>

Changes made to the textbox bound to the SelectedItem Property is reflected back to the DataGrid, but changes made to the textbox bound to the VM Property do not.

using System.Collections.ObjectModel;

using CommunityToolkit.Mvvm.ComponentModel;

namespace PhoneAssistant.WPF.Features.ServiceRequests;

public sealed partial class ServiceRequestsMainViewModel : ObservableObject, IServiceRequestsMainViewModel
{
    public ObservableCollection<ServiceRequest> ServiceRequests { get; } = new();

    [ObservableProperty]
    private ServiceRequest _selectedSR;

    partial void OnSelectedSRChanged(ServiceRequest value)
    {
        VmProperty = value.BoundToVMProperty;
    }

    [ObservableProperty]
    // Neither of these notifies update the datagrid
    [NotifyPropertyChangedFor(nameof(ServiceRequests))]   
    [NotifyPropertyChangedFor(nameof(SelectedSR))]
    private string _vmProperty;
    
    partial void OnVmPropertyChanged(string value)
    {
        SelectedSR.BoundToVMProperty = value;
    }

    public Task LoadAsync()
    {
        ServiceRequests.Add(new ServiceRequest() { Id = 1, BoundToSelected = "SomeValue1", BoundToVMProperty = "AnotherValee1"});
        ServiceRequests.Add(new ServiceRequest() { Id = 2, BoundToSelected = "SomeValue2", BoundToVMProperty = "AnotherValee2" });
        ServiceRequests.Add(new ServiceRequest() { Id = 3, BoundToSelected = "SomeValue3", BoundToVMProperty = "AnotherValee3" });
        return Task.CompletedTask;
    }
}


public sealed class ServiceRequest
{
    public int Id { get; init; }
    public string BoundToSelected { get; set; }
    public string BoundToVMProperty { get; set; }
}

How do I get these changes to update the datagrid?

1

There are 1 best solutions below

2
Taufiq Abdur Rahman On

You bind the DataGrid to BoundToVMProperty but TextBox to VmProperty

 <DataGridTextColumn
                Width="auto"
                Binding="{Binding BoundToVMProperty}"
                Header="BoundToVMProperty" />

 <TextBox
         Grid.Column="1" Margin="0,0,5,0"
         Text="{Binding VmProperty}" />

change the TextBox Binding

     <TextBox
         Grid.Column="1" Margin="0,0,5,0"
         Text="{Binding SelectedSR.BoundToVMProperty }" />