【问题标题】:How To Customize CellStyle For DataGrid Columns And Rows如何为 DataGrid 列和行自定义 CellStyle
【发布时间】:2017-03-04 16:24:24
【问题描述】:

所以我有一个日历和一个按钮。在我选择日期并单击按钮后,程序应该从 sql 数据库中获取所选日期的数据。我在数据表中收集这些数据,我想在数据网格中显示这个数据表。这是我的幕后代码:

Private Sub btnFiltro_Click(sender As Object, e As RoutedEventArgs) Handles btnFiltro.Click
    Dim dt As DataTable
    dt = b.fillDataGrid(from.SelectedDate)
    dataGrid.ItemsSource = dt.DefaultView

End Sub

Public Function fillDataGrid(ByVal Data As Date) As DataTable
    Dim dt As New DataTable()
    Dim cmd As New SqlCommand("SELECT [Statusi] FROM [Database1].[dbo].[Table1] WHERE Data = @Data", conn)
    cmd.Parameters.AddWithValue("@Data", Data)
    cmd.CommandType = CommandType.Text
    Dim adp As New SqlDataAdapter(cmd)
    adp.Fill(dt)
    Return dt
End Function

这就是我在数据网格上显示数据的方式。我现在想要做的是,我想将状态列下单元格的值等于“Humbese”的行的前景色更改为红色。我试着这样做:

<DataGrid attributes here... >
            <DataGrid.CellStyle>
                <Style TargetType="{x:Type DataGridCell}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Status}"  Value="Humbese" >
                            <Setter Property="Foreground" Value="Red" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.CellStyle>
        </DataGrid>

但只有当我在该特定单元格中手动编写“Humbese”时,这才符合我的要求。我想要的是,自动更改颜色,换句话说,当我单击按钮时,我希望行的前景色已经是红色,如果它的单元格包含字符串“Humbese”。 你知道怎么做吗?

编辑 1: 我创建了一个新项目来尝试您的代码,这是我的完整代码: XAML:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:datagridExample"
    mc:Ignorable="d"
    Title="MainWindow" Height="385.993" Width="739.716">
<Window.Resources>

    <Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Status}"  Value="Humbese" >
                <Setter Property="Background" Value="Red" />
                <Setter Property="Foreground" Value="White" />
                <Setter Property="FontWeight" Value="Bold" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

</Window.Resources>

<Grid>

    <!--
<DataGrid ItemsSource="{Binding Data}" 
          CellStyle="{StaticResource DataGridCellStyle1}" />

-->

    <DataGrid x:Name="dg" ItemsSource="{Binding Data}" 
          AutoGenerateColumns="False" >
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Ora}"
                            Width="*"
                            Header="Date"/>
            <DataGridTextColumn Binding="{Binding Status}" 
                            CellStyle="{StaticResource DataGridCellStyle1}"
                            Width="*"
                            Header="Status" />
        </DataGrid.Columns>
    </DataGrid>


    <Button VerticalAlignment="Bottom" Click="Button_Click">LOAD</Button>
    <Calendar x:Name="from" HorizontalAlignment="Left" Margin="253,91,0,0" VerticalAlignment="Top"/>

</Grid>

MainWindow.xaml.vb:

Class MainWindow

Dim vm As Class1
Sub New()


    InitializeComponent()
    vm = New Class1()

    DataContext = vm

End Sub

Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
    vm.LoadData(from.SelectedDate())
End Sub
End Class

Class1.vb(您的视图模型类):

Public Class Class1
Public Property Data() As MyDataTable
    Get
        Return m_Data
    End Get
    Set
        m_Data = Value
    End Set
End Property
Private m_Data As MyDataTable

Public Sub New()
    Data = New MyDataTable()
End Sub

Public Sub LoadData(dataaa As Date)
    Data.loadData(dataaa)
End Sub
End Class

MyDataTable.vb:

Imports System.Data.SqlClient
Imports System.Data

Public Class MyDataTable
Inherits DataTable
Dim conn As SqlConnection
Dim stringBuilder As SqlConnectionStringBuilder
Dim statusi As Integer()

Sub New()
    connectTo()
    Columns.Add("Date", GetType(DateTime))
    Columns.Add("Statusi", GetType(String))
End Sub

Public Sub connectTo()
    stringBuilder = New SqlConnectionStringBuilder()
    stringBuilder.DataSource = "DESKTOP-CPTM4LG\SQLEXPRESS"
    stringBuilder.InitialCatalog = "database1"
    stringBuilder.IntegratedSecurity = True

    conn = New SqlConnection(stringBuilder.ToString())
End Sub

Public Sub loadData(data As Date)
    Dim cmd As New SqlCommand("SELECT [Ora], [Status] FROM [database1].[dbo].[table1] WHERE Data = @Data", conn)
    cmd.Parameters.AddWithValue("@Data", data)
    cmd.CommandType = CommandType.Text
    Dim adp As New SqlDataAdapter(cmd)
    adp.Fill(Me)


End Sub

结束类

【问题讨论】:

  • 整行还是单元格?
  • 整行。我知道 TargetType 是 DataGridCell 但由于某种原因,当我在该特定单元格中手动写入“Humbese”时,它会改变整行的颜色。
  • 请您提供代码和按钮。这将有助于更具体地回答

标签: .net wpf vb.net xaml datagrid


【解决方案1】:

要更改特定列的单元格样式,请将您的样式应用于该特定列:

    <DataGrid ItemsSource="{Binding Data}" 
              AutoGenerateColumns="False" >
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Date}"
                                Width="*"
                                Header="Date"/>
            <DataGridTextColumn Binding="{Binding Status}" 
                                CellStyle="{StaticResource DataGridCellStyle1}"
                                Width="*"
                                Header="Status" />
        </DataGrid.Columns>
    </DataGrid>

要更改特定行中所有列的单元格样式,请将样式应用于DataGrid

    <DataGrid ItemsSource="{Binding Data}" 
              CellStyle="{StaticResource DataGridCellStyle1}" />

风格:

    <Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Status}"  Value="Humbese" >
                <Setter Property="Background" Value="Red" />
                <Setter Property="Foreground" Value="White" />
                <Setter Property="FontWeight" Value="Bold" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

编辑:添加完整代码:

XAML:

<Window x:Class="WpfApplication313.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication313"
    mc:Ignorable="d"
    Title="MainWindow" 
    Height="300" 
    Width="300">
<Window.Resources>

    <Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Status}"  Value="Humbese" >
                <Setter Property="Background" Value="Red" />
                <Setter Property="Foreground" Value="White" />
                <Setter Property="FontWeight" Value="Bold" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

</Window.Resources>

<Grid>

    <!--
    <DataGrid ItemsSource="{Binding Data}" 
              CellStyle="{StaticResource DataGridCellStyle1}" />

    -->

    <DataGrid ItemsSource="{Binding Data}" 
              AutoGenerateColumns="False" >
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Date}"
                                Width="*"
                                Header="Date"/>
            <DataGridTextColumn Binding="{Binding Status}" 
                                CellStyle="{StaticResource DataGridCellStyle1}"
                                Width="*"
                                Header="Status" />
        </DataGrid.Columns>
    </DataGrid>


    <Button VerticalAlignment="Bottom" Click="Button_Click">LOAD</Button>

</Grid>

代码隐藏:

public partial class MainWindow : Window
{
    MyViewModel vm;

    public MainWindow()
    {
        InitializeComponent();

        vm = new MyViewModel();
        DataContext = vm;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        vm.LoadData();
    }
}

视图模型:

public class MyViewModel
{
    public MyDataTable Data { get; set; }

    public MyViewModel()
    {
        Data = new MyDataTable();
    }

    public void LoadData()
    {
        // loading data from DB here
        Data.LoadData();
    }
}

编辑 2: 没关系,但添加用于填充 DataTable 的代码,使其更加清晰。

public class MyDataTable : DataTable
{
    public MyDataTable()
    {
        Columns.Add("Date", typeof(DateTime));
        Columns.Add("Status", typeof(string));
    }

    public void LoadData()
    {
        // for simplicity, please assume data loaded from DB here

        for (int i = 1; i <= 10; i++)
        {
            DataRow dr = NewRow();
            dr["Date"] = DateTime.Now.AddDays(-i).Date;
            dr["Status"] = string.Format("Status {0}", i);
            Rows.Add(dr);
        }

        Rows[2]["Status"] = "Humbese";
        Rows[4]["Status"] = "Humbese";
        Rows[7]["Status"] = "Humbese";
    }
}

编辑 3: 您的代码的问题是列名不一致:DataTable 将其声明为 Statusi,而绑定使用 Status。你的代码在我修复后工作:

【讨论】:

  • 非常感谢您的回答。这看起来很棒,但它不适合我。我一定犯了一些错误,我真的是 xaml 的初学者。所以我把 Style 标签放到 windows 资源中,我不知道这是否是正确的做法。而且我不明白,我应该在 itemsource 属性中给出什么参数。
  • 这也只有当我在那个特定的单元格中手动写“Humbese”时才有效:/
  • 我想我在 itemsource 属性中遗漏了一些东西。我应该在这里写什么而不是数据:itemsource =“{Binding data}”。而且我仍然不明白如果我在单击按钮时设置它,为什么要添加这个 itemsource 属性:dataGrid.itemsource = dt.defaultView
  • 请看我的EDIT,我刚刚添加了完整代码
  • 但是我需要看看你是如何填充数据网格的,新的编辑并没有真正的改变。但无论如何,非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
相关资源
最近更新 更多