Flexgrid WPF ImageCell Binding

Posted by: ray on 23 September 2022, 8:16 pm EST

    • Post Options:
    • Link

    Posted 23 September 2022, 8:16 pm EST - Updated 3 October 2022, 11:25 pm EST

    I want to know if this is possible:

    I want to build a WPF MVVM app bound to the viewmodel.

    I want to create a dataset of complex objects. I want to bind each flexgrid cell to each field in the dataset. This means, I want not only the displayed text but all of the fgcell properties to be set by the field they are attached to. As the status of the data fields change the cells will update as usual with INotifyPropertyUpdate. Example: If a Booking field is populated then the cell shows plain text with a white background and no image (or 1px transparent). The booking is updated, so the background changes to green and the image is a green tick. The booking is cancelled; the font is red and strike through, the bg is grey, and the image is a red “X”.

    The cells update every time just by updating the underlying dataset.

    Is this possible with this version of the control?

  • Posted 23 September 2022, 8:20 pm EST

    Also, can most of the same be done with the Headers?

  • Posted 26 September 2022, 11:17 pm EST

    Hi Raymond,

    You can create different data templates for each case of booking status and store them in the DataTemplateSelector class.

    Please see the following code snippet:

    
    <Window.Resources>
        <DataTemplate x:Key="unknownStatusTemplate">
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
        <DataTemplate x:Key="reservedTemplate">
            <StackPanel Orientation="Horizontal">
                <Image Source="/Resources/tick.png" Width="10" Height="10" VerticalAlignment="Center"/>
                <TextBlock Text="{Binding Name}" Background="Green" Width="100"/>
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="cancelledTemplate">
            <StackPanel Orientation="Horizontal">
                <Image Source="/Resources/x_mark.png" Width="10" Height="10" VerticalAlignment="Center"/>
                <TextBlock Text="{Binding Name}" Background="Gray"  Width="100" Foreground="Red" TextDecorations="Strikethrough"/>
            </StackPanel>
        </DataTemplate>
        <local:MyTemplateSelector x:Key="myDatatemplateSelector" UnknownStatusTemplate="{StaticResource unknownStatusTemplate}" 
                                  ReservedTemplate="{StaticResource reservedTemplate}" CancelledTemplate="{StaticResource cancelledTemplate}"/>
    </Window.Resources>
    
    

    And then override CellFactory’s CreateCellContent() method to set the content based on selected template as the following code:

    public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange rng)
    {
       
        if (rng.Column == 1)
        {
            bdr.DataContext = (Booking)(grid.Rows[rng.Row].DataItem);
            bdr.Child = (System.Windows.UIElement)_myTemplateSelector.SelectTemplate((Booking)(grid.Rows[rng.Row].DataItem), grid).LoadContent();
        }
        else
        {
            base.CreateCellContent(grid, bdr, rng);
        }
    }
    
    

    Kindly refer to the attached sample for full implementation. ImageCellBindBooking.zip

    Best Regards, Aastha

  • Posted 11 October 2022, 5:48 am EST - Updated 11 October 2022, 5:53 am EST

    Hello Aastha. You appear to be working on a static column. I will be working on the cell that I click. I cannot seem to get past this error:

  • Posted 13 October 2022, 3:09 pm EST

    Hi Raymond,

    It seems like you are trying to bind your flexgrid with a DataTable, which is why you are getting the error shown in the snapshot provided by you. In this case, the DataItem returned will be of type DataRowView. Please see the following code:

    bdr.DataContext = (System.Data.DataRowView)(grid.Rows[rng.Row].DataItem);
    bdr.Child = (System.Windows.UIElement)_myTemplateSelector.SelectTemplate((System.Data.DataRowView)(grid.Rows[rng.Row].DataItem), grid).LoadContent();


    Please find attached the sample modified according to your requirement. ImageCellBindBooking_Mod.zip

    Regards,

    Aastha

  • Posted 21 October 2022, 11:09 pm EST

    Thanks Aastha. I’m not getting much time to work on this project atm. I did get your example to work but integrating it into my db is proving more difficult. I will put a couple of hours into it today.

    Thank you for your assistance.

  • Posted 22 October 2022, 2:34 am EST

    Aastha I need to intercept the cell that was clicked before hitting CreateCellContent

  • Posted 27 October 2022, 1:54 am EST

    Hello Aastha.

    I have looked hard at your code. You are binding to a defined column called “Status”. This is not possible for me. I need to bind the column or cell that the object is in. Look again at the image above that I supplied. The cell must get the information it needs from the object it contains.

    Can you help with this please. The documentation is not very friendly in this case.

    Thank you.

  • Posted 28 October 2022, 12:59 am EST

    Hi Raymond,

    Apologies for the delay in response.

    We are working on your requirement. Your patience is greatly appreciated while we work towards resolving this issue.

    Thanks and regards,



    Aastha

  • Posted 30 October 2022, 11:12 pm EST - Updated 31 October 2022, 2:30 am EST

    Hi Raymond,

    As per your requirement, we have created a sample that contains columns with Booking type objects whose template gets updated according to the ‘Status’ of the Booking object. Considering your use case, we have not defined any column for “Status”. In the attached sample, whenever you click on the cell with the ‘Booking’ type object, its template gets updated according to the information stored in the object it is bound to.

    It seems that you are using FlexGrid .NET6 control, hence we have updated the solution accordingly. We have overridden GridCellFactory’s PrepareCell() method to update the cells that have been clicked. Please see the following code snippet:

    public override void PrepareCell(GridCellType cellType, GridCellRange range, GridCellView cell, Thickness internalBorders)
    {
        if (_cells.Contains((range.Row, range.Column)))
        {
            cell.DataContext = (Booking)Grid[range.Row, range.Column];
            cell.Content = (FrameworkElement)_myTemplateSelector.SelectTemplate((Booking)Grid[range.Row, range.Column], Grid).LoadContent();
        }
        else
        {
            base.PrepareCell(cellType, range, cell, internalBorders);
        }
    }

    Note: In case you are working on .NET framework edition , you can implement this logic by overriding ApplyCellStyles() method of CellFactory class.

    Please refer to the attached sample for implementation. (See ImageCellTemplateBooking.zip)

    Regards,

    Aastha

  • Posted 2 November 2022, 12:35 am EST

    Hello Aastha.

    Thank you for the sample, I will look at it now.

    Re: “It seems that you are using FlexGrid .NET6 control…” I have purchased the latest version of WPF controls. I did find them difficult to get running. I assume from this comment that I am not using the correct version in my application?

  • Posted 2 November 2022, 8:31 pm EST

    Hi Raymond,

    Owning ComponentOne’s newest license entitles you to both the .NET and the .NET framework C1 controls. The APIs for both differ in their definition.

    You can use Flexgrid 4.5.2 and 4.6.2 version controls for building the .NET framework application and Flexgrid 6.0 controls for NET6 target applications.

    Since we were uncertain about which FlexGrid API you referred to in your project, we covered both cases in our comment.

    Moreover, we encourage you to build your application on NET 6.0 target framework as it is the latest long-term support release.

    Regards,

    Aastha

  • Posted 2 November 2022, 10:54 pm EST

    Hello Aastha.

    Yes I am targeting the latest frameworks; .Net6.0 , soon to be .Net 7.

    I see that “Flexgrid 6.0” in Nuget it is listed as C1.WPF.Grid I took that to mean it was something other than a flexgrid and that is the reason I used the 4.8. That matter is cleared up now. I have changed to C1.WPF.Grid

    Thank you for the code sample that you wrote for me. I am trying to find time to work on it. At a glance I see that the cells are passed in per click. Since my grid updates per change of calendar day and any changes to the underlying dataset, I will be hoping for the whole grid / cells to “format itself” on INotifyPropertyUpdate.

    Cheers,

    Ray.

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels