locked
cell background RRS feed

  • Question

  • Hello.
    I have to show the background of a grid with cells of two colors from a dictionary with a class with columnname and line as an index and a string of color brush as a value.
    I thought so many ways but I have not come at the head. I searched on google and i saw many example with triggers and converters but I should send my  dictionary to the converter, in somehow, perhaps with a eventagregator or a binding and then call my converter for all cells.
    In winforms easily risolvevo with an event, in WPF does not really know how to do it, maybe it is simple but mentally different.
    I ask advice to you, thanks
    .

    i try this:

    <dxg:GridControl.View>
                    <dxg:TableView ShowTotalSummary="True" Name="view" AllowEditing="False" CellTemplateSelector="{StaticResource myCellTemplateSelector}"/>
                </dxg:GridControl.View>
    but i can't send my dictionary to my custom myCellTemplateSelector

    Wednesday, June 15, 2016 5:42 AM

Answers

  • I don't follow how your markup is related to your question. You ask about setting background based on index and column then show us some datatriggers which are using selectionstate and no dictionary.

    These seem to be two different things.

    As a result, I don't follow what you're trying to achieve.

    I also don't understand the control(s) you're using, because I've never used devexpress controls.

    I know what a (Microsoft) datagrid is built from - and it's pretty complicated to set background and avoid selection state interfering. Especially if you have to look up a brush from a dictionary based on multiple criteria.

    I don't know what a GridControl and TableView produce and this is likely to be significant.

    You should clarify what you intend doing and post your question in a forum which supports the controls you are using.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Friday, June 17, 2016 8:10 AM

All replies

  • There is no gridcontrol and tableview in wpf.

    Is this a Grid, some sort of itemscontrol... or what?

    Could you please clarify what you have and provide your dictionary.

    You could maybe do this by putting a control in whatever this is, behind the other content.

    That could work out where it is and look up the brush out the dictionary, set the fill of a rectangle which'll then fill the cell.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Wednesday, June 15, 2016 10:50 AM
  • sorry i'm using devexpress and prism 5.

    this is my class:

    using DevExpress.Xpf.Core;
    using DevExpress.Xpf.Editors.Internal;
    using DevExpress.Xpf.Grid;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Controls;
    using System.Windows.Media;
    using Microsoft.Practices.ServiceLocation;
    using Microsoft.Practices.Prism.Events;
    using Microsoft.Practices.Prism.PubSubEvents;
    using ViewModels.Events;
    
    namespace HelpersEx
    {
        public class MyCellTemplateSelector : DataTemplateSelector
        {
            Dictionary<int, int> _cells = new Dictionary<int, int>();
            public MyCellTemplateSelector()
            {
                IEventAggregator eventAggregator;
                IEventAggregator agg = ServiceLocator.Current.GetInstance<IEventAggregator>();
                agg.GetEvent<Events.EventCellStyle>().Subscribe(saveCells);
                
            }
            public void saveCells(Dictionary<int, int> cells)
            {
                _cells = cells;
                IEventAggregator agg = ServiceLocator.Current.GetInstance<IEventAggregator>();
                agg.GetEvent<Events.RefreshImportDatagrid>().Publish(true);
            }
            public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
            {
    
                DevExpress.Xpf.Grid.CellEditor cellEditor = container as DevExpress.Xpf.Grid.CellEditor;
                EditGridCellData gridCellData = item as EditGridCellData;
                StackVisibleIndexPanel backgroundBorder = cellEditor.Parent as StackVisibleIndexPanel;
                if (_cells.Count > 0)
                    backgroundBorder.Background = Brushes.Yellow;
                else
                    backgroundBorder.Background = Brushes.Red;
    
                return base.SelectTemplate(item, container);
            }
        }
    }
    

    and in view:

       <dxg:GridControl AutoGenerateColumns="RemoveOld"  ItemsSource="{Binding data}">
                                    <dxg:GridControl.Columns>
    
                                        <dxg:GridColumn FieldName="tb_categoria"  >
                                            
                                        </dxg:GridColumn>
                                    </dxg:GridControl.Columns>
                                    <dxg:GridControl.View>
    
                                        <dxg:TableView  AllowPerPixelScrolling="True" ShowTotalSummary="True" AllowGrouping="False" AllowEditing="False" AllowFilterEditor="False" ShowGroupPanel="False" CellTemplateSelector="{StaticResource myCellTemplateSelector}"/>
                                 </dxg:GridControl.View>
      
                                </dxg:GridControl>

    CellTemplateSelector="{StaticResource myCellTemplateSelector}"

    so i not able to refresh the grid from my class can i use a trigger?.


    thanks and sorry.

    Wednesday, June 15, 2016 5:06 PM
  • Sorry but this forum is for support of Microsoft products, and this is a third party control you're working with.

    You should ask on devexpress forums:

    https://community.devexpress.com/forums/

    .

    If this was a datagrid then you could probably use a multibinding and bind to the alternationindex for the index plus the column name.

    The multiconverter could get a reference to your dictionary from application.current.resources.

    Or you could do the work a row viewmodel and expose a dictionary of brushes which you build as the viewmodel is constructed.

    .

    But since this is a third party control I've never used, I don't know how it works.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles


    • Edited by Andy ONeill Wednesday, June 15, 2016 6:19 PM
    Wednesday, June 15, 2016 6:08 PM
  • i replace all with:

     <ResourceDictionary>
                <local:TrueIfSelectedOrFocused x:Key="TrueIfSelectedOrFocused"/>
                <SolidColorBrush x:Key="red" Color="#FF0000"></SolidColorBrush>
                <SolidColorBrush x:Key="green" Color="Green"></SolidColorBrush>
                <SolidColorBrush x:Key="white" Color="White"></SolidColorBrush>
                <SolidColorBrush x:Key="black" Color="Black"></SolidColorBrush>
                
              
                    <Style x:Key="CustomRowStyle" TargetType="{x:Type dxg:GridRowContent}" BasedOn="{StaticResource {dxgt:GridRowThemeKey ResourceKey=RowStyle}}">
                  
                    <Style.Triggers>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=SelectionState, Converter={StaticResource TrueIfSelectedOrFocused}}" Value="1" />
                               </MultiDataTrigger.Conditions>
                                   <Setter Property="Background" Value="{StaticResource white}" />
                                    <Setter Property="Foreground" Value="{StaticResource black}" />
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=SelectionState, Converter={StaticResource TrueIfSelectedOrFocused}}" Value="2" />
                            </MultiDataTrigger.Conditions>
                                <Setter Property="Background" Value="{StaticResource green}" />
                            <Setter Property="Foreground" Value="{StaticResource black}" />
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=SelectionState, Converter={StaticResource TrueIfSelectedOrFocused}}" Value="3" />
                            </MultiDataTrigger.Conditions>
                                <Setter Property="Background" Value="{StaticResource red}" />
                            <Setter Property="Foreground" Value="{StaticResource black}" />
                        </MultiDataTrigger>
                    </Style.Triggers>
                </Style>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="pack://application:,,,/risorse;component/risorse.xaml"/>
                    
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>


    It work , but only if i select a row and only for this row because

    Binding Path=SelectionState

    For instantly change the color what property i can send ?

    focus?

    this is my converter for the test:

    using DevExpress.Xpf.Core;
    using DevExpress.Xpf.Editors.Internal;
    using DevExpress.Xpf.Grid;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Controls;
    using System.Windows.Media;
    using Microsoft.Practices.ServiceLocation;
    using Microsoft.Practices.Prism.Events;
    using Microsoft.Practices.Prism.PubSubEvents;
    using ViewModels.Events;
    using System.Windows.Input;
    using System.Windows.Markup;
    using System.Globalization;
    using System.Windows.Data;
    
    namespace HelpersEx
    {
        public class TrueIfSelectedOrFocused : IValueConverter
        {
            Dictionary<int, int> _dic = null;
            IEventAggregator _evagg = null;
            public TrueIfSelectedOrFocused()
            {
                _evagg = ServiceLocator.Current.GetInstance<IEventAggregator>();
                _evagg.GetEvent<Events.EventCellStyle>().Subscribe(Change);
            }
    
            private void Change(Dictionary<int,int> b)
            {
                _dic = b;
    
            }
            #region IValueConverter Members
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                try
                {
                    //switch ((SelectionState)value)
                    //{
                    //    case SelectionState.Selected:
                    //    case SelectionState.Focused:
                    //    case SelectionState.FocusedAndSelected:
                    //        return true;
                    //    case SelectionState.None:
                    //        return false;
                    //    default:
                    //        return false;
                    //}
                }
                catch (Exception ex)
                {
                    // Log error here.
                }
                if (_dic == null)
                    return 3;
                else
                    return 2;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return Binding.DoNothing;
            }
            #endregion
        }
    }
    

    i trig an event with the eventaggregator, but when the event is raised change only the selected row.........

    How i can refresh all the rows?

    thanks.


    Thursday, June 16, 2016 11:45 AM
  • This isn't a Microsoft control you're working with.

    That means it's out of scope of the msdn forums.

    And if you want support on devexpress controls you should be asking in their forum.

    https://community.devexpress.com/forums/

    .

    If this was a datagrid I would bind the background in a cellstyle and use a multibinding with a multiconverter to set it.

    You can set that on a datagridcell whose background would be on top of the row background.

    But you're not using a datagrid, you're using something else.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Thursday, June 16, 2016 3:12 PM
  • first i would understand the concept for the datagrid of windows so at limit i see if is possible to apply that on my datagrid or i can use for this project  windows control datagrid.
    Why in your mode the grid is totaly refreshed and repainted and in my no?
    i ask for the windows control.

    can you help me bit more with two rows of code?

    thanks.

    Friday, June 17, 2016 3:38 AM
  • I don't follow how your markup is related to your question. You ask about setting background based on index and column then show us some datatriggers which are using selectionstate and no dictionary.

    These seem to be two different things.

    As a result, I don't follow what you're trying to achieve.

    I also don't understand the control(s) you're using, because I've never used devexpress controls.

    I know what a (Microsoft) datagrid is built from - and it's pretty complicated to set background and avoid selection state interfering. Especially if you have to look up a brush from a dictionary based on multiple criteria.

    I don't know what a GridControl and TableView produce and this is likely to be significant.

    You should clarify what you intend doing and post your question in a forum which supports the controls you are using.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Friday, June 17, 2016 8:10 AM