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!

Labels: , , , ,