wpf datagrid前台绑定到项目的属性programmaticaly

时间:2016-04-21 20:54:17

标签: c# wpf xaml binding datagrid

我有一个WPF DataGrid控件,其中包含运行时生成的列。由于ItemsSource我设置了ExamineExampleDataGridItem的通用列表:

public class ExamineExamplesDataGridItem
{
    public List<string> PredictiveAttributeValues { get; set; }
    public string DecisiveAttributeValue { get; set; }
    public string ExaminedAttributeValue { get; set; }

    public Brush ExaminedAttributeValueColor
    {
        // if I set a debug point here, I'll get there, but it makes no sense
        get
        {
            return DecisiveAttributeValue == null || ExaminedAttributeValue == null
                ? Brushes.Black
                : DecisiveAttributeValue.Equals(ExaminedAttributeValue) ? Brushes.Green : Brushes.Red;
        }
        set { }
    }
}

将字段绑定到DataGrid实例时,除了着色外,一切正常:

List<ExamineExamplesDataGridItem> items = new List<ExamineExamplesDataGridItem>();

// several columns, works fine
for (int i = 0; i < _attributeTypeSet.PredictiveAttributeTypes.Count; i++)
{
    DataGridComboBoxColumn attributeTypeColumn = new DataGridComboBoxColumn()
    {
        TextBinding = new Binding("PredictiveAttributeValues[" + i + "]")
    };
    dataGrid.Columns.Add(attributeTypeColumn);
}

// prev last column, works fine
DataGridComboBoxColumn decisiveComboBoxColumn = new DataGridComboBoxColumn()
{
    CellStyle =
        new Style(typeof (DataGridCell)) {Setters = {new Setter() {Property = ForegroundProperty, Value = Brushes.Blue}}}
};
dataGrid.Columns.Add(decisiveComboBoxColumn);

// last column, which content I want to color
DataGridTextColumn examinedColumn = new DataGridTextColumn()
{
    ElementStyle = new Style()
    {
        TargetType = typeof(TextBlock),
        Setters =
        {
            // this works, but..
            // new Setter(TextBlock.ForegroundProperty, Brushes.Red)

            // ... I need this one. It calls ExaminedAttributeValueColor property, but displays black color anyway
            new Setter(TextBlock.ForegroundProperty, new Binding("ExaminedAttributeValueColor"))
        }
    }
};
dataGrid.Columns.Add(examinedColumn);

dataGrid.ItemsSource = items;

填充ItemsSource时,其颜色保持黑色。我还尝试绑定CellStyle而不是ElementStyle,如下所示:

CellStyle = new Style()
{
    TargetType = typeof(DataGridCell),
    Setters =
    {
        new Setter(DataGridCell.ForegroundProperty, new Binding("ExaminedAttributeValueColor"))
    }
}

但它不起作用,就像ElementStyle一样。我发现了很多故障排除,但它们都是关于XAML编码的。是否有可能从C#代码中做我想做的事情?我该怎么办?我应该使用CellStyleElementStyle属性以外的其他内容吗?我看到了FontStyle的{​​{1}}属性,但据我所知它只定义了一个字体系列。

1 个答案:

答案 0 :(得分:0)

这是一个非常快速和基本的示例,在DataGrid中设置单元格的前景和背景,并在MVVM模式之后为项目的下拉集合添加Combobox

首先我们创建一个BasePropertyChanged类实现INotifyPropertyChanged,它继承在我们想要更改属性值的任何地方来通知UI

public class BasePropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

这是你的'ExamineExamplesDataGridItem'课程,我不得不在这里做些什么因为我不知道你的样子......

public class ExamineExamplesDataGridItem : BasePropertyChanged
{


    public ExamineExamplesDataGridItem()
    {
        PredictiveAttributeValues = new List<string>();
        PredictiveAttributeValues.Add("Predict 1");
        PredictiveAttributeValues.Add("Predict 2");
        PredictiveAttributeValues.Add("Predict 3");
        PredictiveAttributeValues.Add("Predict 4");
        PredictiveAttributeValues.Add("Predict 5");
    }

    private List<string> _PredictiveAttributeValues;

    public List<string> PredictiveAttributeValues
    {
        get { return _PredictiveAttributeValues; }
        set { _PredictiveAttributeValues = value; NotifyPropertyChanged("PredictiveAttributeValues"); }
    }

    private string _Coll1;

    public string Coll1
    {
        get { return _Coll1; }
        set { _Coll1 = value; NotifyPropertyChanged("Coll1"); }
    }

    private string _Coll2;

    public string Coll2
    {
        get { return _Coll2; }
        set { _Coll2 = value; NotifyPropertyChanged("Coll2"); }
    }
}

}

这是您的View(XAML)所绑定的ViewModel,其任务是简单地维护应用程序中的数据状态,当数据发生变化时(此处在ViewModel中)作为用户输入的结果或从外部源(即数据库)更新,然后更新视图(使用Binding和DataContext)

class Base_ViewModel : BasePropertyChanged
{

    private List<ExamineExamplesDataGridItem> _items;

    public List<ExamineExamplesDataGridItem> items
    {
        get { return _items; }
        set { _items = value; NotifyPropertyChanged("items"); }
    }

    public Base_ViewModel()
    {
        items = new List<ExamineExamplesDataGridItem>();
        items.Add(new ExamineExamplesDataGridItem() { Coll1 = "Row 1 Col 1", Coll2 = "Row 1 Col 2" });
        items.Add(new ExamineExamplesDataGridItem() { Coll1 = "Row 2 Col 1", Coll2 = "Row 2 Col 2" });
        items.Add(new ExamineExamplesDataGridItem() { Coll1 = "Row 3 Col 1", Coll2 = "Row 3 Col 2" });
    }
}

这是XAML,请注意所有样式,设置器和绑定是如何在XAML中完成的......

<Grid>

    <DataGrid Name="DataGrid1" AutoGenerateColumns="False" ItemsSource="{Binding items}" >
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Combobox">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox SelectedIndex="0" ItemsSource="{Binding PredictiveAttributeValues}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate> 
            </DataGridTemplateColumn>
            <DataGridTextColumn Binding="{Binding Coll1}" Header="Column 1">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell">
                        <Setter Property="Background"  Value="Blue" />
                        <Setter Property="Foreground" Value="White" />
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
            <DataGridTextColumn Binding="{Binding Coll2}" Header="Column 2">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell">
                        <Setter Property="Background"  Value="Red" />
                        <Setter Property="Foreground" Value="White" />
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

</Grid>

,最后是数据上下文......现在,我已经在代码隐藏中设置了这个仅仅是为了简化这个例子但通常即使这一行代码都会进入XAML但是需要更复杂的XAML代码,因为您需要使用应用程序名称在XAML中添加对该ViewModel的引用,我不知道[您的]应用程序调用了什么或您的文件夹结构

// in the Code - Behind file of you WPF Window
InitializeComponent();
// Set Data Context for the View
this.DataContext = new Base_ViewModel();

它看起来像我知道的很多代码,但当你分解它时,确实没有多少代码。问题是你现在可以自由地设计和修改XAML中的UI控件....最后的测试就是这个....在一个纯粹的MVVM应用程序中你应该能够注释掉所有的UI控件(在XAML)和代码STILL编译没有任何错误.....