我正在试图弄清楚如何将DataGrid的数据源绑定到'cells'的ObservableCollection。特别是,我有一个ObservableCollection,它包含以下类的实例:
public class Option : INotifyPropertyChanged
{
public Option()
{
}
// +-+- Static Information +-+-
public double spread = 0;
public double strike = 0;
public int daysToExpiry = 0;
public int put_call; // 0 = Call, 1 = Put
// Ticker References
public string fullTicker = "";
public string underlyingTicker = "";
//+-+-Properties used in Event Handlers+-+-//
private double price = 0;
public double Price
{
get { return price; }
set
{
price = value;
NotifyPropertyChanged("Price");
}
}
//+-+-+-+- Propoerty Changed Event & Hander +-+-+-+-+-//
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
在我的DataGrid上,我想显示这些类(我使用PriceColumns和每个单元格中的'strike'变量),使它们按“underlyingTicker”[这是一个4个字符的字符串]和“spread”[接受后台编码中定义的6个可能值中的1个]。
目前,当我将DataGrid的DataContext绑定到ObservableCollection时,它会将每个'Option'显示为一行 - 我无法弄清楚如何指定对这些对进行分组的内容......
这就是我的datagrid现在的样子:
非常感谢 - kcross!
答案 0 :(得分:1)
和Dtex一样,我并不完全明白你想做什么。但我试图进行简化,希望能让你开始。
您必须传递DataGrid
和IEnumerable
(最好是ObserrvableCollection
)个对象。单个对象将转换为行,这些对象的属性将转换为列标题。
因此,如果您希望列标题表示标准偏差的倍数(右?),则必须创建一个具有这些倍数作为属性的对象。生成的单元格将包含Option
类。要表示这些,您必须定义DataTemplate或覆盖ToString()函数。从你的例子来看,我认为你做过前者。
背后的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace DataGridSpike
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private List<Option> _unsortedOptions;
private ObservableCollection<OptionRow> _groupedOptions;
public ObservableCollection<OptionRow> GroupedOptions
{
get { return _groupedOptions; }
set { _groupedOptions = value; }
}
public MainWindow()
{
var rnd=new Random();
InitializeComponent();
//Generate some random data
_unsortedOptions=new List<Option>();
for(int element=0;element<50;element++)
{
double column=rnd.Next(-2,3);
int row=rnd.Next(0,9);
_unsortedOptions.Add(new Option { ColumnDefiningValue = column, RowDefiningValue = row });
}
//Prepare the data for the DataGrid
//group and sort
var rows = from option in _unsortedOptions
orderby option.ColumnDefiningValue
group option by option.RowDefiningValue into optionRow
orderby optionRow.Key ascending
select optionRow;
//convert to ObservableCollection
_groupedOptions = new ObservableCollection<OptionRow>();
foreach (var groupedOptionRow in rows)
{
var groupedRow = new OptionRow(groupedOptionRow);
_groupedOptions.Add(groupedRow);
}
//bind the ObservableCollection to the DataGrid
DataContext = GroupedOptions;
}
}
public class OptionRow
{
private List<Option> _options;
public OptionRow(IEnumerable<Option> options)
{
_options = options.ToList();
}
public Option Minus2
{
get
{
return (from option in _options
where option.ColumnDefiningValue == -2
select option).FirstOrDefault();
}
}
public Option Minus1
{
get
{
return (from option in _options
where option.ColumnDefiningValue == -1
select option).FirstOrDefault();
}
}
public Option Zero
{
get
{
return (from option in _options
where option.ColumnDefiningValue == 0
select option).FirstOrDefault();
}
}
public Option Plus1
{
get
{
return (from option in _options
where option.ColumnDefiningValue == 1
select option).FirstOrDefault();
}
}
public Option Plus2
{
get
{
return (from option in _options
where option.ColumnDefiningValue == 2
select option).FirstOrDefault();
}
}
}
public class Option:INotifyPropertyChanged
{
public override string ToString()
{
return string.Format("{0}-{1}", RowDefiningValue.ToString(),ColumnDefiningValue.ToString());
}
private double _columnDefiningValue;
public double ColumnDefiningValue
{
get{return _columnDefiningValue;}
set{_columnDefiningValue = value;
OnPropertyChanged("ColumndDefiningValue");
}
}
private int _rowDefiningValue;
public int RowDefiningValue
{
get{return _rowDefiningValue;}
set{_rowDefiningValue = value;
OnPropertyChanged("RowDefiningValue");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
XAML:
<Window x:Class="DataGridSpike.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid ItemsSource="{Binding}"/>
</Grid>
</Window>