Patrick
Patrick

Reputation: 2583

Change Datagrid cell number of decimals

I have a datagriId bound to an observable collection. I want to store the correct values in the observable collection (with all decimals) but I want to see less decimals in the datagrid. So I tried this Change DataGrid cell value programmatically in WPF and some similar others.

In the end what I need is to change the value of the datagrid when the event is fired.

private void Datagrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
  DataGridRow row = e.Row;
  var pePCDmise = row.Item as PcDmisData.Measures;

  DataGridRow rowContainer = dtgResults.GetRow(0);
  DataGridCell  d = dtgResults.GetCell(rowContainer, 3);
}

So the rowcontainer above is not null but when I try to get the cell value I get a null exception. Particularly:

public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column)
{
  if (row != null)
  {
    DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);

    if(presenter == null)
    {
      grid.ScrollIntoView(row, grid.Columns[column]);
      presenter = GetVisualChild<DataGridCellsPresenter>(row);
    }

    DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
    return cell;
  }
  return null;
}

the presenter above is null and it's null also after having entered the if.

How can I make it work? Thanx

---ADD---- Aside from the aforementioned problem how can I make a one-way-bind? I have set the datagrid bind with

 dtgResults.ItemsSource = easyRunData.olstMeasures;

but now I want to change the dtgResults number of decimals only and not the observable collection value.

Upvotes: 0

Views: 1198

Answers (2)

bars222
bars222

Reputation: 1660

If you generating columns for DataGrid in code behind you can write something like this. Xaml part.

<DataGrid Name="dgTest" AutoGenerateColumns="False">
</DataGrid>

ValueConverter code. In examle I used rounding for 3 digits, but you can pass this as ConverterParameter and improve code.

public sealed class DecimalConverter : IValueConverter
{
    public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
    {
        double result = 0;
        if ( value is double )
            result = Math.Round( ( double )value, 2 );
        return result;
    }

    public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
    {
        throw new NotImplementedException();
    }
}

Initializing code.

DataGridTextColumn valColumn = new DataGridTextColumn();
Binding valBinding = new Binding( "SomeVal" );
valBinding.Converter = new DecimalConverter();
valColumn.Binding = valBinding;
dgTest.Columns.Add( valColumn );
dgTest.ItemsSource = Objects;

My test Observable collection is named Objects and containing objects with double property SomeVal and realization INotifyPropertyChanged behaviour.

private double _someVal;

public double SomeVal
{
    get { return _someVal; }
    set { _someVal = value; NotifyPropertyChanged( "SomeVal" ); }
}

Update Typical INotifyPropertyChanged realization.

#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected void NotifyPropertyChanged( String info )
{
    if ( PropertyChanged != null )
    {
        PropertyChanged( this, new PropertyChangedEventArgs( info ) );
    }
} 

Upvotes: 0

AnjumSKhan
AnjumSKhan

Reputation: 9827

Simplest way to change DataGridCell value is to use Loaded event handler of TextBlock :

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Area, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"  Loaded="TextBlock_Loaded"/>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>



private void TextBlock_Loaded(object sender, RoutedEventArgs e)
{
    TextBlock tb = ((TextBlock)sender);

    // do anything with textblock    

    if (tb.Text == 10)
    {
        tb.Background = Brushes.Plum;
    }
}

If AutogenerateColumns = true, then we need to handle DataGridCell's Loaded event.

<DataGrid.Resources>
     <Style TargetType="DataGridCell">
         <EventSetter Event="DataGridCell.Loaded" Handler="DataGridCell_Load"/>
     </Style>
</DataGrid.Resources>

private void DataGridCell_Load(object sender, RoutedEventArgs e)
        {
            DataGridCell cell = sender as DataGridCell;

            if (cell.Column.Header.ToString() == "MyColumn")
                ((TextBlock)cell.Content).Text = ...do something... ;

            /* to get current row and column */
            DataGridColumn col = cell.Column;
            Dgrd2.CurrentCell = new DataGridCellInfo(cell);
            DataGridRow row = (DataGridRow)Dgrd2.ItemContainerGenerator.ContainerFromItem(Dgrd2.CurrentItem);             
        }

Upvotes: 1

Related Questions