Bart Pinnock
Bart Pinnock

Reputation: 163

DataGridTemplateColumn update

I'm reworking an old control to WPF. I need to make a datagrid which displays a list of alarms. The first column of the datagrid is a datagridtemplate column which holds a flag icon and the date. When the user presses the button the alarms are acknowledged and the flag icon has to disappear. I'm using an MVVM pattern.

The problem is that I cannot seem to update the flag in the datagridtemplate column. When I change the acknowledge status from 0 to 1 (the alarm was ackonwledged), the flag does not disappear. When I reload the control and get the alarms again from the server, the flag does not show up again indicating that its status has actually been updated in the server. So somehow my code is working but my UI is not getting updated. I also tried to change the alarm's description in the same way and that column does get updated. (MainViewModelBase implements INotifyPropertyChanged)

The view

<DataGrid x:Class="Kwa.Presentation.Views.AlarmList.AlarmList"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
          xmlns:local="clr-namespace:Kwa.Presentation.Views.AlarmList"
          xmlns:components="clr-namespace:Kwa.Presentation.Components"
          xmlns:converters="clr-namespace:Kwa.Presentation.Converters"
          xmlns:Trans="clr-namespace:Kwa.Presentation.Resources"
          mc:Ignorable="d" 
          d:DesignHeight="500" d:DesignWidth="750"
          ItemsSource="{Binding Alarms}"
          SelectedItem="{Binding SelectedAlarm}"
          IsSynchronizedWithCurrentItem="True"
          CanUserResizeColumns="True" IsReadOnly="True" CanUserReorderColumns="False" CanUserSortColumns="False" SelectionMode="Single" CanUserAddRows="False"
          Background="White" RowHeaderWidth="0" AutoGenerateColumns="False" GridLinesVisibility="None" RowHeight="{Binding Rowheight}" FrozenColumnCount = "1"
          ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto"
          x:Name="AlarmFramework"
          SizeChanged="AlarmFramework_SizeChanged"
          >

    <DataGrid.Resources>
        <converters:AlarmSeverityToColorConverter x:Key="AlarmSeverityToColorConverter"/>
        <converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
        <converters:InvertedBoolToVisibilityConverter x:Key="InvertedBoolToVisibilityConverter"/>
</DataGrid.Resources>

    <DataGrid.Columns>

        <DataGridTemplateColumn Header="{x:Static Trans:TranslatedResources.AlarmColumnHeaderTime}" Width="auto" HeaderStyle="{StaticResource WithButt}">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <components:FlagControl VerticalAlignment="Center" Height="15" Width="15" FlagColor="{Binding Severity, Converter={StaticResource AlarmSeverityToColorConverter}}"
                                                Visibility="{Binding AckStatus, Converter={StaticResource InvertedBoolToVisibilityConverter}, Mode=TwoWay}"/>
                        <TextBlock Text="{Binding DateTimeString}" Padding="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                    </StackPanel>

                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <DataGridTextColumn Header="{x:Static Trans:TranslatedResources.AlarmColumnHeaderSeverity}" Binding="{Binding SeverityString}" Width="auto" HeaderStyle="{StaticResource WithoutButt}"/>

        <DataGridTextColumn Header="{x:Static Trans:TranslatedResources.AlarmColumnHeaderDescription}" Binding="{Binding Description}"  d:Width="400" Width="*" HeaderStyle="{StaticResource WithoutButt}"/>



    </DataGrid.Columns>
</DataGrid>

The AlarmList View Model

public class AlarmListViewModel : MainViewModelBase
{
#region Properties
    private ObservableCollection<AlarmEntryViewModel> _alarms = new ObservableCollection<AlarmEntryViewModel>();
    public ObservableCollection<AlarmEntryViewModel> Alarms
    {
        get { return _alarms; }
        set
        {
            _alarms = value;
            RaisePropertyChanged(() => Alarms);
        }
    }

    private AlarmEntryViewModel _selectedAlarm;
    public AlarmEntryViewModel SelectedAlarm
    {
        get { return _selectedAlarm; }
        set
        {
            _selectedAlarm = value;
            RaisePropertyChanged(() => SelectedAlarm);
        }
    }

    private int _acknowledgeAllowed;
    public int AcknowledgeAllowed
    {
        get { return _acknowledgeAllowed; }
        set
        {
            _acknowledgeAllowed = value;
            RaisePropertyChanged(() => AcknowledgeAllowed);
        }
    }


    private readonly IActionCommand _acknowledgeCommand;
    public IActionCommand AcknowledgeCommand
    {
        get { return _acknowledgeCommand; }
    }

    public int MaxAcknowledgedAlarm;
    public double RowHeight { get; set; }
    public AlarmEntryViewModel AlarmToSend { get; set; }

    #endregion

    #region Constructor

    public AlarmListViewModel()
    {
        if (!IsInDesignMode)
        {
            RowHeight = 30;
        }

        //Add command
        _acknowledgeCommand = new ActionCommand<double>(p => Acknowledge(p));

    }

    #endregion

 #region Private Methods

        private void Acknowledge(double parameter)
        {
            if (AcknowledgeAllowed == 1)
            {
                try
                {
                    //Get Datagrid width
                    double DatagridWidth = (double)parameter;
                    //Calculate the amount of fully visible alarms
                    int AmountVisible = (int)Math.Floor(DatagridWidth / RowHeight);
                    if (Alarms.Count < AmountVisible)
                    {
                        AlarmToSend = Alarms[Alarms.Count - 1];
                        foreach(AlarmEntryViewModel alarm in Alarms)
                        {
                            alarm.AckStatus = true;
                            alarm.Description = "Iets nieuw";
                        }
                    }
                    else
                    {
                        //Send the last visible alarm, 0 based => -1
                        AlarmToSend = Alarms[AmountVisible - 1];
                        //Go to next visible alarm
                        SelectedAlarm = Alarms[AmountVisible];
                    }
                    //Acknowledge alarms
                    _proxy.Send(AlarmToSend.AlarmNumber);

                }
                catch (Exception ex)
                {
                    _viewManager.ShowDialog(new MessageDialogViewModel()
                    {
                        AskAnswer = false,
                        Text = ex.Message,
                        Title = TranslatedResources.AlarmAckSendErrorTitle,
                    });
                }
            }
            else
            {
                _viewManager.ShowDialog(new MessageDialogViewModel()
                {
                    AskAnswer = false,
                    Text = TranslatedResources.AlarmAcknErrorMessage,
                    Title = TranslatedResources.AlarmAcknErrorTitle,
                });
            }


        }

        #endregion

The AlarmListEntry view model

public class AlarmEntryViewModel : MainViewModelBase
    {
    #region Fields
    private readonly IViewManager _viewManager;
    private readonly IDockManager _dockManager;
    private string _description;

    #endregion

    #region Constructor

    public AlarmEntryViewModel()
    {
    }

    #endregion

    #region Model & Proxy

    private Alarm _model;
    public Alarm Model
    {
        set { _model = value; }
    }

    public AlarmListServiceProxy Proxy { get; set; }

    #endregion

    #region Properties

    public DateTime Time { get { return _model.Time; } }

    public string DateTimeString { get { return _model.Time.ToString("dd/MM/yyyy hh:mm:ss"); } }

    public int Severity { get { return _model.Severity; } }

    public string SeverityString
    {
        get
        {
            if (_model.Severity == 0)
                return "Melding";
            if (_model.Severity == 1)
                return "Waarschuwing";
            if (_model.Severity == 2)
                return "Fout";
            else
                return "Niet gekend";
        }
    }

    public string Description 
    { 
        get
        {
            //string substring = _model.Description.Substring(_model.Description.Length - 1);
            //if ( substring.Equals("\n"))
            //{
            //    return _model.Description.Substring(0, _model.Description.Length - 1);
            //}
            //else
            //    return _model.Description;
            return _description;
        }
        set
        {
            _description = value;
            RaisePropertyChanged(() => Description);
        }
    }

    public int AlarmNumber { get { return _model.Number; } }

    public int AcknStatus { get { return _model.AcknStatus; } }

    private bool _ackStatus;
    public bool AckStatus
    {
        get
        {
            if (_model.AcknStatus == 0)
                return false;
            else
                return true;

        }
        set
        {
            _ackStatus = value;
            RaisePropertyChanged(() => AckStatus);
        }
    }

    #endregion


}

Upvotes: 0

Views: 289

Answers (1)

mm8
mm8

Reputation: 169200

You set _ackStatus in the setter but doesn't return the value of this field from the getter in AlarmEntryViewModel. Do this:

private bool _ackStatus;
public bool AckStatus
{
    get
    {
        return _ackStatus;
    }
    set
    {
        _ackStatus = value;
        RaisePropertyChanged(() => AckStatus);
    }
}

Or set the _model.AcknStatus field in the setter:

private bool _ackStatus;
public bool AckStatus
{
    get
    {
        if (_model.AcknStatus == 0)
            return false;
        else
            return true;

    }
    set
    {
        _ackStatus = value;
        _model.AcknStatus = value ? 1 : 0;
        RaisePropertyChanged(() => AckStatus);
    }
}

Upvotes: 1

Related Questions