Avatar
Frantisek Jesatko:19. srpna 14:18

Ahoj mam dotaz na datagrid ve wpf . muzu nejak zmenit barvu pozadi radku podle urcite hodnoty bunky ? Chybi mi Rows i Cells . nevim jestli delat v xaml nebo c#. diky za pomoc

Zkusil jsem: zkousel jsem web nic

Chci docílit: rozliseni zaznamu barevne podle urcitych hodnot

 
Odpovědět 19. srpna 14:18
Avatar
krepsy3
Redaktor
Avatar
krepsy3:19. srpna 15:08

To je problém s datagridem, musíš totiž změnit svůj pohled na datagrid.

Datagrid je kontrolka, která reprezentuje určitá data, která kontrolce binduješ. Což znamená, že mít z kontrolky znova přístup k datům je de facto blbost. Uvědom si, že když DataGridu binduješ určitou kolekci, tak ona ti tu kolekci zobrazí jako tabulku, kde řádky jsou obvykle položky kolekce, jejichž vlastnosti zobrazují sloupce.

A teď - máš-li kolekci dat, kterou předáš datagridu, víš, že někde v té kolekci se nacházejí i data, která se v datagridu zobrazí v buňce, podle které bys chtěl pozadí měnit.

Co z toho plyne? Že data pro barvu pozadí nemáš získat přes datagrid, ale přímo přes kolekci, kterou datagridu binduješ. Pokud chceš ode mě napsat nějaký kód, napiš, co je to za data a na základě čeho chceš pozadí měnit. Napiš mi také XAML, protože mám pocit, že to co chceš dělat se dá zakomponovat přímo do bindingu :)

Nahoru Odpovědět 19. srpna 15:08
Programátor je stroj k převodu kávy na kód.
Avatar
Odpovídá na krepsy3
Frantisek Jesatko:19. srpna 17:27

tady je xaml

<DataGrid x:Name="grd_uni"  HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" MinWidth="600" Margin="185,48,2,6" AlternatingRowBackground="#FFD6CECE" GridLinesVisibility="Vertical" VerticalGridLinesBrush="#FF534B4B"/>

Data do datagridu dostavam z kodu takto :

var  xxx = from z in db.Zasahs
                         from k in db.Adresars
                         from u in db.Uzivateles
                         where z.id_zakaznika == k.ico && z.id_uzivatele == u.Id
                         orderby z.datum descending
                         select new { z.id_zasahu, z.datum, k.nazev, z.pro_technika, z.popis_zavady, z.poslan_vykaz, z.fakturovano, z.fakturovany_dily, z.stav, u.prijmeni, z.upraveno, z.sdileno, z.vytvoreno, z.cislo_stroje };


          grd_uni.ItemsSource = xxx.ToList();

Kde položka fakturovano je hodnota "Ano-Ne" , fakturovany-dily je take hodnota "Ano-Ne"
Podle toho bych rád barvil řádky.
Dále potřebuju předat id z Bindingu tedy hodnotu z_idzasahu.
Díky za pomoc

 
Nahoru Odpovědět 19. srpna 17:27
Avatar
Odpovídá na krepsy3
Frantisek Jesatko:19. srpna 19:01

Je pravda že mam na datagrid z WF jiný pohled. Ve WPF je celý přístup uplně jiný a docela dost s tím zápasím .

 
Nahoru Odpovědět 19. srpna 19:01
Avatar
krepsy3
Redaktor
Avatar
Odpovídá na Frantisek Jesatko
krepsy3:19. srpna 23:47

A tu kolekci z linq dotazu tam binduješ jak?

Nahoru Odpovědět 19. srpna 23:47
Programátor je stroj k převodu kávy na kód.
Avatar
krepsy3
Redaktor
Avatar
Odpovídá na krepsy3
krepsy3:19. srpna 23:56

Jo aha, takže necháváš WPF, ať to dělá samo... Tak to bude stačit udělat si columntemplaty, ve kterých zrealizuješ ty změny pozadí... napiš mi přesně, co chceš, aby ty buňky dělaly

Nahoru Odpovědět 19. srpna 23:56
Programátor je stroj k převodu kávy na kód.
Avatar
Odpovídá na krepsy3
Frantisek Jesatko:20. srpna 6:10

Vzhledem k tomu , že přecházím z WF tak binding je věc která mi zůstává utajena. A tak nechávám vše co můžu do v cecku . Jinak teda potřebuju aby sloupec fakturováno pokud obsahuje hodnotu NE tak celý rádek barva červená .

 
Nahoru Odpovědět 20. srpna 6:10
Avatar
Miroslav Majcher:20. srpna 9:05

Jedna z alternativ je napisat si vlastny behavior k danemu datagridu.

/// <summary>
   ///
   /// </summary>
   public class DataGridRowLoadBackgroudBehaviour : Behavior<DataGrid>
   {
       #region OnAttached
       /// <summary>
       ///
       /// </summary>
       protected override void OnAttached()
       {
           base.OnAttached();
           AssociatedObject.LoadingRow += this.AssociatedObject_LoadingRow;
       }
       #endregion

       #region OnDetaching
       /// <summary>
       ///
       /// </summary>
       protected override void OnDetaching()
       {
           base.OnDetaching();
           AssociatedObject.LoadingRow -= this.AssociatedObject_LoadingRow;
       }
       #endregion

       #region AssociatedObject_LoadingRow
       /// <summary>
       ///
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       void AssociatedObject_LoadingRow(object sender, DataGridRowEventArgs e)
       {
            -- v e.Row.DataContext je bindovany object
           Complaint current = e.Row.DataContext as Complaint;
           if (current != null)
           {
               if (!string.IsNullOrEmpty(current.PriorityType))
               {
                   -- tu sa vyhodnocuje, kedy ma mat row inu farbu.
                   if (current.PriorityType.ToUpper() == "A")
                       e.Row.Background = new SolidColorBrush(Colors.Red);
                   else
                       e.Row.Background = null;
               }
               else
                   e.Row.Background = null;
           }
           else
               e.Row.Background = null;
       }
       #endregion
   }

V XAML pre prislusny DataGrid:

<i:Interaction.Behaviors>
         <cUtils:DataGridRowLoadBackgroudBehaviour/>
 </i:Interaction.Behaviors>

kde i je z

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

Kod je kopirovany zo Silverlightu, z jedneho mojho projektu. Bude potreba ho prejst, upravit na WPF, ale princip cez behavior je rovnaky.

M.

 
Nahoru Odpovědět 20. srpna 9:05
Avatar
Odpovídá na Frantisek Jesatko
Matyáš Černohous:20. srpna 17:07

Něco podobného jsem řešil. Dělám to přesně tak jak psal krepsy3. Do DataGridu nabinduju kolekci a změnu dat (např. změna barvy pozadí jedné buňky nebo celého řádku) provádím přes controller. Model implementuje rozhraní INotifyProper­tyChanged, takže kdykoliv změním nějaký item, který mám v kolekci, tak se změna hned projeví v DataGridu.
Binding je sám o sobě dost užitečná věc, protože vlastně můžeš díky tomu měnit skoro jakoukoliv vlastnost.

Tady je moje řešení. Je zde binding dat do jednotlivých DataGridTextCo­lumnů. Nevím jak to je přesně, ale vypadá to, že dědí z textBoxu, takže přes setter můžeš upravovat jakoukoli vlastnost jako kdyby si pracoval s TextBoxem - tudíž i barvu pozadí/textu/rá­mečku... (

<Setter Property="TextBlock.Background" Value="{Binding Color}" />

)

Níže je kód modelu a poté controlleru.

<DataGrid  ItemsSource="{Binding}" HorizontalScrollBarVisibility="Hidden" RowHeaderWidth="0" x:Name="data" Background="White" HorizontalAlignment="Stretch"
                  Margin="1,5" VerticalAlignment="Stretch" BorderBrush="Black" BorderThickness="2,0,2,2" AutoGenerateColumns="False" CanUserResizeRows="False" GridLinesVisibility="All"
                  ScrollViewer.ScrollChanged="data_ScrollChanged" ScrollViewer.CanContentScroll="True" ColumnHeaderDragCompleted="data_ColumnHeaderDragCompleted"
                  LayoutUpdated="data_LayoutUpdated" IsReadOnly="True" CanUserReorderColumns="False" CanUserSortColumns="False" UseLayoutRounding="False" IsManipulationEnabled="True"
                  PreviewMouseWheel="data_PreviewMouseWheel" IsHitTestVisible="False" FontSize="11" FontFamily="Tahoma" >
           <DataGrid.Resources>
               <Style TargetType="{x:Type DataGridCell}">
                   <Style.Triggers>
                       <Trigger Property="DataGridCell.IsSelected" Value="True">
                           <Setter Property="Background" Value="White" />
                           <Setter Property="BorderBrush" Value="Transparent" />
                           <Setter Property="Foreground" Value="Black"/>
                       </Trigger>
                   </Style.Triggers>
               </Style>
           </DataGrid.Resources>
           <DataGrid.Columns>
               <DataGridTextColumn Binding="{Binding Podsestava}" util:DataGridUtil.Name="ses" ClipboardContentBinding="{x:Null}" Header="Podsestava" FontFamily="Tahoma" FontSize="11" >
                   <DataGridTextColumn.ElementStyle>
                       <Style>
                           <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
                       </Style>
                   </DataGridTextColumn.ElementStyle>
               </DataGridTextColumn>
               <DataGridTextColumn Binding="{Binding Pozice}" IsReadOnly="True" util:DataGridUtil.Name="poz" ClipboardContentBinding="{x:Null}" Header="Pozice" FontFamily="Tahoma" FontSize="11">
                   <DataGridTextColumn.ElementStyle>
                       <Style>
                           <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
                           <Setter Property="TextBlock.Cursor" Value="Hand"></Setter>
                           <EventSetter Event="TextBlock.MouseDown" Handler="Click"  />
                           <Setter Property="TextBlock.Background" Value="{Binding Color}" />
                       </Style>
                   </DataGridTextColumn.ElementStyle>
               </DataGridTextColumn>
               <DataGridTextColumn Binding="{Binding Nazev}" util:DataGridUtil.Name="naz" ClipboardContentBinding="{x:Null}" Header="Název" FontFamily="Tahoma" FontSize="11">
                   <DataGridTextColumn.ElementStyle>
                       <Style>
                           <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
                       </Style>
                   </DataGridTextColumn.ElementStyle>
               </DataGridTextColumn>
               <DataGridTextColumn Binding="{Binding Poznamka}" util:DataGridUtil.Name="pozn" ClipboardContentBinding="{x:Null}" Header="Poznámka" FontFamily="Tahoma" FontSize="11">
                   <DataGridTextColumn.ElementStyle>
                       <Style>
                           <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
                       </Style>
                   </DataGridTextColumn.ElementStyle>
               </DataGridTextColumn>
           </DataGrid.Columns>
           <DataGrid.ColumnHeaderStyle>
               <Style TargetType="{x:Type DataGridColumnHeader}">
                   <Setter Property="Background" Value="White"/>
                   <Setter Property="Foreground" Value="Black" />
                   <Setter Property="Margin" Value="0,0,0,0" />
                   <Setter Property="HorizontalContentAlignment" Value="Left" />
                   <Setter Property="BorderThickness" Value="0,2,1,2" />
                   <Setter Property="BorderBrush" Value="Black" />
                   <Setter Property="FontWeight" Value="Bold" />


               </Style>
           </DataGrid.ColumnHeaderStyle>


       </DataGrid>

Model:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace DokumentacePriprava
{
    public class Rozpiska : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public string Podsestava { get; set; }
        public string Pozice { get; set; }
        public string Nazev { get; set; }
        public string Dodavatel { get; set; }
        public string Poznamka { get; set; }

        private string color;

        public string Color
        {
            get { return color; }
            set
            {
                color = value;
                NotifyPropertyChanged();

            }
        }

        public Rozpiska(string podsestava, string pozice, string nazev, string dodavatel, string poznamka)
        {
            Podsestava = podsestava;
            Pozice = pozice;
            Nazev = nazev;
            Dodavatel = dodavatel;
            Poznamka = poznamka;
            Color = "Transparent";

        }

//tohle je nepodstatný
        public string ConvertType(bool en)
        {
            if (en)
            {
                if (SettingsHelper.TypeValues.ContainsKey(TypDiluOrig))
                    return SettingsHelper.TypeValues[TypDiluOrig].Item2;
                else
                    return TypDilu;
            }
            else
            {
                if (SettingsHelper.TypeValues.ContainsKey(TypDiluOrig))
                    return SettingsHelper.TypeValues[TypDiluOrig].Item1;
                else
                    return TypDilu;
            }
        }
    }
}

a controller:

public class RozpiskaController
    {
        private ObservableCollection<Rozpiska> rozpiska = new ObservableCollection<Rozpiska>();

        public RozpiskaController()
        {
        }

                //pridani itemu do kolekce
        public void Add(Rozpiska r)
        {
                rozpiska.Add(r);
        }

                public ObservableCollection<Rozpiska> GetCollection()
        {
            return rozpiska;
        }

//Změna barvy itemu v kolekci - pokud se item z kolekce rovná itemu u kterého chceš zněnit barvu, tak se provede nastavení barvy z paramentru a ihned se ti projeví změna v DataGridu
          public void ChangeColor(Rozpiska r, string hexColor)
        {
            foreach (var rozp in rozpiska)
            {
                if (rozp.Equals(r))
                {
                    rozp.Color = hexColor;
                    break;
                }
            }
        }
}

Vytvoříš si instanci controlleru a přidáš tam itemy. Dále nastavíš u DataGridu ItemSoource na tvoji kolekci a data se zobrazí v DataGridu. Dále pak jen používáš metody z Controlleru. Logiku si doplň podle toho co potřebuješ.

Příklad použití - např po načtení hlavního okna:

private void Window_Loaded(object sender, RoutedEventArgs e)
       {
                       //vytvoreni instance controlleru
                       RozpiskaController rController = new RozpiskaController();
                       //pridani itemu do controlleru
                       rController.Add(new Rozpiska("podst","152","test1","dodavatel","pozn");
                       rController.Add(new Rozpiska("podst1","2","test2545","dodavatel12","pozn heslo");
                       rController.Add(new Rozpiska("ledňáček","1982","popart","kofola","nejlepší vzpomínky");


               //nastavení ItemSource na kolekci
               data.ItemSource = rController.GetCollection();
               //Ted by si tam měl mít zobazeny data

               //změna barvy políčka pozice, pokud se item v kolekci bude rovnat itemu v parametru
               Rozpiska r  = new Rozpiska("podst1","2","test2545","dodavatel12","pozn heslo");
               rController.ChangeColor(r,"#8ff442"); //Druhý řádek bude mít políčko v řádku pozice obarvený na zeleno
               }

Snad ti to pomůže :)

Editováno 20. srpna 17:07
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět 20. srpna 17:07
Avatar
Odpovídá na Matyáš Černohous
Frantisek Jesatko:21. srpna 19:42

diky za navod je az s podivem jak tak jednoduchou vec jde resit slozite. Tim nechci narazet na tebe to vubec :) ale na cely wpf . chapu ze oddelit vzhled od logiky je prehledny ale vrstva ktera obe veci propoji je mi fakt prozatim utajena .

 
Nahoru Odpovědět 21. srpna 19:42
Avatar
Bruce
Člen
Avatar
Odpovídá na Frantisek Jesatko
Bruce:28. srpna 14:37

Taky by to slo udelat pres DataTriggery asi takto

<Style TargetType="Da­taGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding NetworkChecked}" Value="True">
<Setter Property="Bac­kground" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding NetworkChecked}" Value="False">
<Setter Property="Bac­kground" Value="Orange" />
</DataTrigger>
<DataTrigger Binding="{Binding NetworkDataIm­ported}" Value="False">
<Setter Property="Bac­kground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>

 
Nahoru Odpovědět  +1 28. srpna 14:37
Avatar
Odpovídá na Bruce
Frantisek Jesatko:29. srpna 20:10

Ahoj tak toto řešení je uplně nejlepší jednoduchý jako problém sám díky

 
Nahoru Odpovědět 29. srpna 20:10
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 12 zpráv z 12.