Eae Eae - 1 month ago 24
Vb.net Question

how to change foreground color of a datagrid row in wpf on load?

So i have a calendar and a button. After i select the date and click the button, the program is supposed to get the data from the selected date from a sql database. I collect that data in a datatable, and i want to show this datatable in the datagrid. Here's my behind code:

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


This is how i display data on my datagrid. What i want to do now, is that i want to change the foreground color to red of rows where the value of cell under the Status column is equal to "Humbese". And i tried to do that like this:

<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>


But this does what i want only if i manually write "Humbese" in that particular cell. What i want is, to change the color automatically, in other words when i click the button i want the foreground color of the row to already be red, if its cell contains the string "Humbese".
Do you have any idea how to do that?

Answer

In order to change the cell style for a specific column, apply your style to that particular column:

    <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>

enter image description here

In order to change the cell style for all columns in a specific row, apply the style to the DataGrid:

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

enter image description here

Style:

    <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>

EDIT: Adding full-code:

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>

Code-behind:

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();
    }
}

ViewModel:

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

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

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

EDIT 2: It shouldn't matter, but adding code for filling the DataTable, to make it even more clear.

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";
    }
}
Comments