【问题标题】:Change Datagrid cell number of decimals更改 Datagrid 单元格的小数位数
【发布时间】:2015-12-14 10:32:37
【问题描述】:

我有一个绑定到可观察集合的 datagriId。我想在可观察集合中存储正确的值(所有小数),但我想在数据网格中看到更少的小数。 所以我尝试了这个 Change DataGrid cell value programmatically in WPF 还有一些类似的。

最后我需要的是在触发事件时更改数据网格的值。

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);
}

所以上面的行容器不是空的,但是当我尝试获取单元格值时,我得到一个空异常。 特别是:

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;
}

上面的presenter为null,输入if后也为null。

我怎样才能让它工作? 谢谢

---添加---- 除了上述问题外,我如何进行单向绑定?我已经用

设置了数据网格绑定
 dtgResults.ItemsSource = easyRunData.olstMeasures;

但现在我只想更改 dtgResults 的小数位数,而不是可观察的集合值。

【问题讨论】:

  • 也许最好为这一行写ValueConverter,这样会舍入绑定值的数目
  • @bars222 怎么样?你能提供一个实际的例子吗?我正在使用代码隐藏,并且如上所述设置了 dtgResults.ItemsSource = easyRunData.olstMeasures;。我认为从 Datagrid_LoadingRow 工作会更好,因为并非所有列都包含要正确设置的数字。

标签: c# wpf data-binding datagrid cell


【解决方案1】:

更改 DataGridCell 值的最简单方法是使用 Loaded event handlerTextBlock

<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;
    }
}

如果AutogenerateColumns = true,那么我们需要处理DataGridCell的Loaded事件。

<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);             
        }

【讨论】:

  • 这可行,但添加了一个新列。我这样做了:
  • 设置 AutoGenerateColumns = false
  • 这会删除除添加的列之外的所有列。我如何从 TextBlock_Loaded 中知道我指的是哪一行和哪一列?
  • 那行得通!但如果我想让它更通用。即:对不同的datagrid调用同一个例程,然后根据datagrid名称进行切换。我试过 cell.Parent。但那总是空的......
【解决方案2】:

如果您在后面的代码中为DataGrid 生成列,您可以编写类似这样的内容。 Xaml 部分。

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

ValueConverter 代码。在示例中,我使用了 3 位四舍五入,但您可以将其传递为 ConverterParameter 并改进代码。

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();
    }
}

初始化代码。

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

我的测试 Observable 集合被命名为 Objects 并包含具有双重属性 SomeVal 和实现 INotifyPropertyChanged 行为的对象。

private double _someVal;

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

更新典型的INotifyPropertyChanged实现。

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

【讨论】:

  • 感谢您的回复。我是 wpf 的新手。因此,当我复制粘贴您的代码时,我在 NotifyPropertyChanged 这个词上遇到了构建错误。我该如何解决?然后我有各种列,只能在 1-2-3 而不是 0-4- 上使用转换器......我该怎么做?谢谢
  • 1 你应该意识到INotifyPropertyChanged 的行为。 2 您不应该将转换器添加到 0-4-.. 列的绑定中。
猜你喜欢
  • 1970-01-01
  • 2013-01-14
  • 2011-08-13
  • 2013-05-01
  • 2021-04-06
  • 1970-01-01
  • 2015-08-24
  • 2018-06-09
  • 2015-11-19
相关资源
最近更新 更多