Having different CellEditor for different rows (Xceed WPF Grid)

Currently I needed to make an Xceed WPF Grid to have different CellEditors for one column for different rows based on a condition (in my case the condition was the content of the cell). I’ve found no info for a similar situation on Xceed’s Forums. I’ve tried using the CellContentTemplateSelector for that column but after some tests I’ve noticed that when user types in the cell for that column the template disappears. And this was unacceptable. After some brainstorming and with a small hint from Xceed Support I was able to make a solution. I’ll present it to you in this article.

This solution utilizes WPF DataTriggers. So if you are not very familiar with them please read the related articles on MSDN

CellEditor.xaml

<xcdg:CellEditor x:Key="CellEditorSelector">
    <xcdg:CellEditor.EditTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <TextBox x:Name="txtTextBox"
                        Visibility="Visible"
                        />
                <ComboBox x:Name="lstCombo"
                        Visibility="Collapsed"
                        />
                <CheckBox x:Name="chkCheckBox"
                        Visibility="Collapsed"
                        />
            </StackPanel>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:Cell}}
                                                , Path=Content
                                                , Mode=OneWay}"
                                                Value="txt"
                >
                    <Setter TargetName="txtTextBox" Property="Visibility" Value="Visible"/>
                    <Setter TargetName="lstCombo" Property="Visibility" Value="Collapsed"/>
                    <Setter TargetName="chkCheckBox" Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:Cell}}
                                                , Path=Content
                                                , Mode=OneWay}"
                                                Value="lst"
                >
                    <Setter TargetName="txtTextBox" Property="Visibility" Value="Collapsed"/>
                    <Setter TargetName="lstCombo" Property="Visibility" Value="Visible"/>
                    <Setter TargetName="chkCheckBox" Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:Cell}}
                                                , Path=Content
                                                , Mode=OneWay}"
                                                Value="chk"
                >
                    <Setter TargetName="txtTextBox" Property="Visibility" Value="Collapsed"/>
                    <Setter TargetName="lstCombo" Property="Visibility" Value="Collapsed"/>
                    <Setter TargetName="chkCheckBox" Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </xcdg:CellEditor.EditTemplate>
</xcdg:CellEditor>

By assigning the above given CellEditor to a column of and Xceed WPF Grid it will change the editor of the cell to a TextBox if the text in the cell is “txt”, to a ComboBox if the text in the cell is “lst” and to a CheckBox if the text in the cell is “chk”. By default the TextBox will be displayed.

This is a very simple example. I’ll leave to your imagination what else you can do with a similar CellEditor. You can have very complex conditions to choose which template to show. All you have to do is encapsulate the logic in a method and bind to the method in the DataTrigger. Binding property. <

Enjoy the Power WPF!

5 replies
  1. Malik
    Malik says:

    Thanks for explaining the different celleditor for differnt row, But i m facing problem in binding the editable data to these editors, how can i bind the data of different column to these editors and after binding also how can i set them that they update automatically when data is changed.

    Reply
  2. Peter Staev
    Peter Staev says:

    Hi Malik!

    In order the editors to change the data in an object you just have to set the appropriate bindings for Text/SelectedValue/IsChecked of the Textbox/ComboBox/CheckBox that are in the StackPanel in the template.

    So just put a TwoWay binding there to the data you want to change and it will work 😉

    Hope this was helpful.

    Reply
  3. Anonymous
    Anonymous says:

    Hi peter, would you please help me ?
    In xceed how can i find out the value of other column. Its almost same like yours but my trigger will depend on the value of other column. tq. andy

    Reply
  4. Peter Staev
    Peter Staev says:

    Hey there,

    If you mean the previous comment about getting the value of another column in Xceed – I do not think this is possible, or it will be very very complex. This is because here you can easily find the cell that the template was assigned with FindAccestor. Finding another cell will be difficult because you first have to find the DataRow that contains the cell and after that find the cell you want.

    What you can try is make a Converter that you bind to the RelativeSource binding. And in the converter you can traverse the VisualTree of the current cell and on some criteria find your cell and then return its content.

    Hope this was helpfull.
    Peter

    Reply

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published.