Reputation: 2583
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
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
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