WPF DataGrid - 绑定到'单元'的集合

时间:2012-05-02 18:28:33

标签: c# wpf datagrid

我正在试图弄清楚如何将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现在的样子: enter image description here

非常感谢 - kcross!

1 个答案:

答案 0 :(得分:1)

和Dtex一样,我并不完全明白你想做什么。但我试图进行简化,希望能让你开始。 您必须传递DataGridIEnumerable(最好是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>