1

Im my viewmodel I have a list of my custom objects of type IPC.Device bound to a property defined as

private ObservableCollection<IPC.Device> _devices;

public ObservableCollection<IPC.Device> Devices
{
    get
    {
        return _devices;
    }

    set
    {
        _devices = value;
        RaisePropertyChangedEvent ("Devices");
    }
}

I use the ObservableCollection to populate a DataGrid, that I create with the following XAML (unnecessary parts are not shown)

<DataGrid x:Name="MainGrid" ItemsSource="{Binding Path=Devices}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False">
    <DataGrid.Columns>
        ....
        <DataGridTemplateColumn Header="{Binding Source={x:Static p:Resources.device_status},
                                                 Converter={StaticResource CapitalizeFirstLetterConverter}}"
                                Width="*" IsReadOnly="True">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=deviceStatus, Converter={StaticResource DeviceStatusToStringConverter}, Mode=OneWay}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        ....
    </DataGrid.Columns>
    <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <Views:CameraLoginControl  Visibility="{Binding Path=deviceStatus, Converter={StaticResource DeviceStatusUnauthorizedConverter}, Mode=OneWay}" />
                <Views:TestSelectionControl Visibility="{Binding Path=deviceStatus, Converter={StaticResource DeviceStatusOnlineConverter}, Mode=TwoWay}" />
            </StackPanel>

        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
</DataGrid>

When I update the ObservableCollection byt replacing an item with its updated copy I can see that the Datagrid is correctly updated, the row is updated and the DeviceStatusToStringConverter is fired. Unfortunately, the DeviceStatusUnauthorizedConverter and DeviceStatusOnlineConverter are never fired again, so the RowDetailsTemplate is still the one of the previous item.

What am I doing wrong?

Update

The IPC.Device is, stripped of unnecessary fields:

public class Device
{
    [DataMember]
    public DeviceStatus deviceStatus { get; set; }

    ...
}

You see [DataMember] beacsue I use this structure in many places, also for IPC. I have other Propertied marked [DataMember], thus I would exclude this as the reason why this happens. DeviceStatus is an enum.

Ottavio Campana
  • 4,088
  • 5
  • 31
  • 58

1 Answers1

1

There are several possibilities to do it.

  • You can implement INotifyPropertyChanged for the Device.deviceStatus, then you don't need to replace an object in ObservableCollection, just modify the property.
  • You can replace the whole ObservableCollection Devices = new ObservableCollection...
  • You can remove and insert an element:
    Devices.RemoveAt(i);
    Devices.Insert(i, new Device());
Rekshino
  • 6,954
  • 2
  • 19
  • 44
  • I'd like to implement INotifyPropertyChanged for Device.deviceStatus, but I don't know how to do it. Can you please give me a hint? – Ottavio Campana Mar 09 '20 at 16:05
  • @OttavioCampana [What's the best way to call INotifyPropertyChanged's PropertyChanged event?](https://stackoverflow.com/questions/488587/whats-the-best-way-to-call-inotifypropertychangeds-propertychanged-event?noredirect=1&lq=1) – Rekshino Mar 10 '20 at 07:21
  • Eventually the RemoveAt + Insert solution was the best one. – Ottavio Campana Mar 10 '20 at 08:52