Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
20
Xamdatagrid binding fields to multiple converters
posted

Hi Team,

I have one requirement where I have a Xamdatagrid and it gets bound to a collection. I have defined a style with a target type as CellValuePresenter and set the foreground property of the row using a converter. In this converter, I return the color based on a property value that I get In the converter when it executes, so if that property value is true then the row foreground color becomes gray. Second, the scenario is in the same xamdatagrid I have a column name as the 'Marks' column, this column's cells are integers. I have written a data template, and in that data template, I have a text block, for the text attribute I have a converter that converts the negative numbers by adding brackets in front and back of number. for the Foreground attribute, I have a converter that changes the color of the number based on if the number is positive or negative. 

The requirement is I want the entire row's foreground to be in gray color including the 'Marks' column when a property value is true for that row, if the property value is false then the entire row should be normal except the 'Marks' column cell value, which should be red in color if the cell value is negative and green color if the cell value if positive. How should I achieve this?

The row is set in gray color when the converters execute but the 'Marks' column cell's value does not changes. 

  • 2500
    Verified Answer
    Offline posted

    Hi Vivek,

    Thank you for posting to Infragistics Community!

    I have been looking into the described configuration and created a sample with a XamDataGrid aiming to reproduce it. By the way, please feel free to provide own isolated samples as well, which will make communicating the setup and requirements more straightforward.

    So, what I can say is that it is expected that the Foreground style on the columns’ DisplayTemplate TextBlock takes precedence over whatever style is set on the CellValuePresenter object, as it is defined directly on that element.

    Additionally, the described logic is entirely derived on application level, therefore, there would not be something built into the grid to address the specific scenario, so the solution is rather a matter of tuning the converters logic.

    Taking the described as an example, what I can suggest is modifying the DataTemplate TextBlock’s Foreground binding and converter to the following: firstly, bind the value to the entire data item. More about this approach can be found in the Configuring Template Field topic in our documentation:

    <igWPF:TemplateField Name="Coal">
                                <igWPF:TemplateField.DisplayTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{igWPF:TemplateEditorValueBinding Converter={StaticResource integersConv}}"
                                                   Foreground="{Binding Path=(igEditors:TemplateEditor.Editor).DataContext.DataItem, Converter={StaticResource negativeFgConv}, RelativeSource={RelativeSource Self}}"></TextBlock>
                                    </DataTemplate>
                                </igWPF:TemplateField.DisplayTemplate>
                            </igWPF:TemplateField>

    This would allow the converter to reason about the data property that is responsible for the gray color of the CellValuePresenters. It can check that condition with priority and return the color as “Gray” in case it is satisfied. Only then the negative/positive check should be performed, so that the foreground is modified based on the sign.

    The sample’s "NegativeFgConverter" class shows some custom logic for demo purposes:

    internal class NegativeFgConverter : IValueConverter
        {
            private string regionString = "Country";
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value == null)
                {
                    return "Black";
                }
    
                DataModel dm = value as DataModel;
                string val = dm.Region.ToString();
                string numPart = val.Substring(this.regionString.Length);
                if (int.Parse(numPart) % 2 == 0)
                {
                    return "Gray";
                }
                else
                {
                    int coal = int.Parse(dm.Coal.ToString());
                    if (coal < 0)
                    {
                        return "Red";
                    }
                    else
                    {
                        return "Green";
                    }
                }
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }

    Below is a screenshot from the sample demonstrating the final result. The cells foreground is gray for records having the numeric part of the “Region” value an even number. As you can see, all the cells are gray-colored in this case, due to the above converter’s logic, as well as the others included in the sample.

    Please, keep in mind that this is a suggestion revolving around custom logic about the data and there might exist better approaches to achieving this. Please, feel free to further customize it as per your own application needs.

    In conclusion, please, consider the suggested approach and test the below attached sample on your side.

    Best regards,
    Bozhidara Pachilova
    Associate Software Developer

    3056.XDGStyles.zip

  • 2500
    Offline posted in reply to Vivek Kumar

    Hi Vivek,

    I am glad that you find my suggestion helpful.

    To address your subsequent query, based on the description I understand you would like to have a single Style, targeting the CellValuePresenter that sets the Foreground color based on the “IsAnimal” property, however, that color should also depend on the field of each separate cell? Please, elaborate further in case my understanding is incorrect.

    Since the DataContext of the CellValuePresenter is the DataRecord, it has access to all the data properties, which you are already familiar with. Having this in mind, though, the CellValuePresenter is not provided a context of the Field. Consequently, since styles, targeting the CellValuePresenter can be defined separately for each field, this is the approach I would suggest adpoting.

    Additionally, the same converter could be used, and the field could be differentiated in it by passing a ConverterParameter, for instance:

                            <igWPF:TextField Name="Region">
                                <igWPF:TextField.CellValuePresenterStyle>
                                    <Style TargetType="{x:Type igWPF:CellValuePresenter}">
                                        <Style.Setters>
                                            <Setter Property="Foreground"
                                                    Value="{Binding DataItem.IsSomething, Converter={StaticResource cvpForegroundConverter}, ConverterParameter='Region'}" />
                                        </Style.Setters>
                                    </Style>
                                </igWPF:TextField.CellValuePresenterStyle>
                            </igWPF:TextField>
                            <igWPF:Field Name="Coal">
                                <igWPF:Field.CellValuePresenterStyle>
                                    <Style TargetType="{x:Type igWPF:CellValuePresenter}">
                                        <Style.Setters>
                                            <Setter Property="Foreground"
                                                    Value="{Binding DataItem.IsSomething, Converter={StaticResource cvpForegroundConverter}, ConverterParameter='Coal'}"/>
                                        </Style.Setters>
                                    </Style>
                                </igWPF:Field.CellValuePresenterStyle>
                            </igWPF:Field>

    Alternatively, conditional styles could also be defined with the help of Data Triggers:

                            <igWPF:TextField Name="Nuclear">
                                <igWPF:TextField.CellValuePresenterStyle>
                                    <Style TargetType="{x:Type igWPF:CellValuePresenter}">
                                        <Style.Setters></Style.Setters>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding DataItem.IsSomething}" Value="true">
                                                <Setter Property="Foreground"
                                                        Value="Red" />
                                            </DataTrigger>
                                            <DataTrigger Binding="{Binding DataItem.IsSomething}"
                                                         Value="false">
                                                <Setter Property="Foreground"
                                                        Value="Green" />
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </igWPF:TextField.CellValuePresenterStyle>
                            </igWPF:TextField>

    If you require any firther assistance on the matter, please, let me know.

    Best regards,
    Bozhidara Pachilova

    4861.XDGStyles2.zip