【问题标题】:WPF - Binding multiple values to a datagrindWPF - 将多个值绑定到数据研磨
【发布时间】:2011-04-28 11:54:27
【问题描述】:

已更新:清理主题并总结。

嗨, 我有一个数据表填充,其中每个单元格都是这样的类

class CValue{
     public object Value;
     public Brush Quality;
     private int m_quality;

     public override String toString(){
           return Value.toString();
     }
}

我的数据网格绑定在数据表上,并且运行良好。 但我的目标是根据质量值切换单元格的背景颜色。

我打算使用数据模板,但根本不知道它是如何工作的......

<dg:DataGrid  Name="DataGridResult" IsReadOnly="True" AutoGenerateColumns="False"
     BorderThickness="1" BorderBrush="{DynamicResource clBLACK}"
     CanUserReorderColumns="False"
     ItemsSource="{Binding Path=Result}">
          <dg:DataGrid.Resources>
             <Style TargetType="{x:Type dg:DataGridCell}">
                <Style.Setters>
                   <Setter Property="Background" Value="{Binding [1].Quality}"/>
                </Style.Setters>
             </Style>
          </dg:DataGrid.Resources>           
          <dg:DataGrid.ItemTemplate>
             <DataTemplate>
                <dg:DataGridCell>
                   </dg:DataGridCell>
             </DataTemplate>
           </dg:DataGrid.ItemTemplate>
</dg:DataGrid>

实际上,如果背景设置器的值设置为“蓝色”,则所有单元格都是蓝色的,所以没关系,但我找不到将它绑定到我的属性的方法。 [1] 似乎返回了该行的第 1 列...

如何动态设置单元格? 因为我有动态数量的列,但是所有的 CValue 类型。

【问题讨论】:

  • 您真的不想拥有画笔以提高质量,对吧?当然可以,但我想说使用转换器或 DataTrigger 进行值绑定会更整洁。
  • 是的,但实际上我需要将一些值和颜色放入配置中,所以在代码中。我正在寻找最简单的方法:)
  • 好的,因为在这种情况下你不需要任何转换器,只需直接绑定到质量 Background={Binding Quality}。您想要一个带有 .cs 的应用的简短示例来演示我认为您正在尝试做的事情吗?
  • 是的,这真的很有帮助:)

标签: c# wpf data-binding datagrid datatemplate


【解决方案1】:

好的。因此,对于整个示例数据绑定到模型的 Brush,而不是使用转换器、样式等。对于以下 cs -code:

class CValue
{
    public string Value { get; set; } // Notice we use properties for binding and not fields
    public Brush Quality { get; set; } // Notice we use properties for binding and not fields
    private int m_quality;

    public override String ToString()
    {
        return Value.ToString();
    }
} 

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        // Databind the list
        myGrid.ItemsSource = new List<CValue>
                          {
                              new CValue
                                  {
                                      Value = "First", 
                                      Quality = new SolidColorBrush(Color.FromArgb(255, 0, 255, 255))},
                              new CValue
                                  {
                                      Value = "Second",
                                      Quality = new SolidColorBrush(Color.FromArgb(255, 255, 0, 255))
                                  },
                              new CValue
                                  {
                                      Value = "Third", 
                                      Quality = new SolidColorBrush(Color.FromArgb(0, 255, 255, 255))
                                  }
                          };
    }
}

您可以使用 xaml 作为行样式(注意样式上的 TargetTypeAutoGenerateColumns="false")来绑定行颜色和值:

<Controls:DataGrid x:Name="myGrid" AutoGenerateColumns="False">

    <Controls:DataGrid.RowStyle>
        <Style TargetType="{x:Type Controls:DataGridRow}">
            <Setter Property="Background" Value="{Binding Quality}" />
        </Style>
    </Controls:DataGrid.RowStyle>

    <Controls:DataGrid.Columns>
        <Controls:DataGridTemplateColumn Header="Value">
            <Controls:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Label Content="{Binding Value}" />
                </DataTemplate>
            </Controls:DataGridTemplateColumn.CellTemplate>
        </Controls:DataGridTemplateColumn>
    </Controls:DataGrid.Columns>

</Controls:DataGrid>

希望对你有帮助!

【讨论】:

  • 嗨,非常感谢,我想的不是很远,我遇到了这个错误:System.Windows.Data 错误:39:BindingExpression 路径错误:找不到“质量”属性'对象' ''DataRowView' (HashCode=9847817)'。绑定表达式:路径=质量; DataItem='DataRowView' (HashCode=9847817);目标元素是'DataGridRow'(名称='');目标属性是'Background'(类型'Brush'),也许是因为我正在绑定一个数据表,其中每个单元格都是一个CValue
  • 您仍然将错误的东西绑定到 ItemSource,您不想绑定数据网格而是绑定列表。你在哪里设置 DataContext?
  • 所以我可以尝试类似 ItemsSource={Binding Result.Rows} ?
  • 不完全...您必须有一个 CValue 实例列表,对吧?这是您要绑定的那个。在这种情况下,“结果”是什么,似乎是 DataGrid?您不想绑定到要绑定到实际结果列表、数组 (/collection) 的 DataGrid。
【解决方案2】:

保持着色在 XAML 中可见的一个好方法是使用绑定到质量的样式。我们将此样式放在模板上方的一些资源字典中,就像我在 DataGrid.Resources 中一样。

<Controls:DataGrid>
    <Controls:DataGrid.Resources>
        <Style TargetType="{x:Type Controls:DataGridCell}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Quality}" Value="0">
                    <Setter Property="Background" Value="Red" />
                </DataTrigger>

                <DataTrigger Binding="{Binding Quality}" Value="0">
                    <Setter Property="Background" Value="Blue" />
                </DataTrigger>

            </Style.Triggers>
        </Style>
    </Controls:DataGrid.Resources>
    <Controls:DataGrid.ItemTemplate>
        <DataTemplate>
            <Controls:DataGridCell>
            </Controls:DataGridCell>
        </DataTemplate>
    </Controls:DataGrid.ItemTemplate>
</Controls:DataGrid>

更新:

为了能够对值进行数据绑定或任何使用这样的转换器:

[ValueConversion(typeof(int), typeof(SolidColorBrush))]
public class QualityToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Cast value
        int intValue = (int) value;

        if (intValue == 1)
            return new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));

        return new SolidColorBrush(Color.FromArgb(255, 0, 0, 255));
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException("TwoWay binding not supported!");
    }
}

将其绑定到 XAML 中,如下所示:

<Window.Resources>
    <WpfApplication1:QualityToColorConverter x:Key="ColorConverter" />
</Window.Resources>

<Controls:DataGridCell Background="{Binding Quality, Converter={StaticResource ColorConverter}}">
</Controls:DataGridCell>

【讨论】:

  • 我认为在我的 CValue 类中创建一个“转换器”并直接绑定到颜色更容易,因为我使用位掩码来检查质量...我应该使用数据模板吗?
  • 更新了转换器示例,如果您需要任何调整方面的帮助,请发表评论。
  • 附带说明,我注意到您的 Quality 是一个“对象”实例,这意味着 ValueConversion 属性需要是 typeof(object), typeof(SolidColorBrush) 虽然我认为您应该输入质量,因为这会改善您的编译时错误检查。
  • 任何想法:在“对象”“DataRowView”(HashCode=57338399)上找不到“质量”属性。绑定表达式:路径=质量; DataItem='DataRowView' (HashCode=57338399);目标元素是'DataGridCell'(名称='');目标属性是“背景”(类型“画笔”) System.Windows.Data 错误:39:BindingExpression 路径错误:在“对象”“DataRowView”(HashCode=57338399)上找不到“值”属性。绑定表达式:路径=值; DataItem='DataRowView' (HashCode=57338399);目标元素是'DataGridCell'(名称='');目标属性是“内容”(类型“对象”)
  • 似乎您没有将 CValue 类绑定为数据模板中的数据上下文。您如何将源绑定到 DataGrid?
【解决方案3】:

您应该使用DataTemplateSelector 类来执行此逻辑。 场景描述如下:

  • 创建数据模板集;
  • DataTemplateSelector Class 派生并在那里实现选择适当 DataTemplate 的逻辑,如 MSDN 文章中所述;
  • 将您的自定义DataTemplateSelector 定义为指定x:Key 属性的资源;
  • 将所需对象绑定到定义的DataTemplateSelector 资源。

更新

当您需要像评论中提到的人那样完全重新设计单元格时,上面的方法效果最好。

因此,对于此任务,您应该创建转换器,将其定义为资源并将其添加到您的绑定中:

<!--somewhere in resources-->
<QualityToBackgroundConverter x:Key="qualityToBackgroundConverter "/>

然后绑定将如下所示:

Background="{Binding Quality, Converter={StaticResource qualityToBackgroundConverter }}" 

最后是转换器:

[ValueConversion(typeof(Quality), typeof(Brush))]
public class QualityToBackgroundConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            Quality quality = (Quality)value;           
            switch (quality)
            {
                case 0: return Brushes.Red;
                case 1: return Brushes.Yellow;
                case 2: return Brushes.Green;
                default: return Brushes.Transparent;
            }   
        }
        return Brushes.Transparent;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw NotImplementedException();
    }
}

【讨论】:

  • 仅仅为了改变背景而替换整个模板有点不合时宜,你不觉得吗?使用样式或转换器应该更实用。
  • 我有点害怕 DataTemplateSelector 它似乎有点矫枉过正,不是吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 1970-01-01
  • 2011-02-02
  • 2016-04-30
  • 2010-10-23
  • 1970-01-01
相关资源
最近更新 更多