KingTravisG
KingTravisG

Reputation: 1336

WPF and ObservableCollection<T>

I have an ObservableCollection<IRuleCondition> that I want to display - the IRuleCondition interface is used by 2 different classes I want to display, a RuleCondition that simply displays one rule condition (info such as priority, property to check and so on), and a RuleConditionGroup, that can contain 2 or more RuleConditions, grouped in such a way that any of the conditions could match, or all etc.

In the XAML I was wondering is there a way to display a different ListView.ItemTemplate depending on what the type is that it encounters in the ObservableCollection<IRuleCondition>? Or would I need to implement two different ObservableCollections?

Upvotes: 4

Views: 12612

Answers (3)

parapura rajkumar
parapura rajkumar

Reputation: 24423

Here is a simple example of how this works

This is how the objects are defined

public interface Person
{
    string Name { get; set; }
}

public class Manager : Person
{
    public string Name { get; set; }
}

public class Employee : Person
{
    public string Name { get; set; }
    public string ManagerName { get;set;}
}

This is the MainWindow code behind

public partial class MainWindow : Window
    {
        ObservableCollection<Person> mPeople = new ObservableCollection<Person>();

        public ObservableCollection<Person> People
        {
            get
            {
                return mPeople;
            }
        }

        public MainWindow()
        {
            DataContext = this;
            mPeople.Add( new Employee{ Name = "x" , ManagerName = "foo"});
            mPeople.Add( new Manager { Name = "y"});

            InitializeComponent();
        }
    }

This is the MainWindow XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WpfApplication1"
        Title="MainWindow"
        Height="350"
        Width="525">
    <Window.Resources>
        <DataTemplate  DataType="{x:Type my:Employee}">
            <StackPanel Background="Green" Width="300">
                <TextBlock Text="{Binding Name}" />
                <TextBlock Text="{Binding ManagerName}" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate  DataType="{x:Type my:Manager}">
            <StackPanel Background="Red"
                        Width="300">
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>

    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding People}"></ListBox>
    </Grid>
</Window>

As you can see there are two datatemplates one for Manager and one for Employee

enter image description here

And this is how the crappy output looks like. Notice the green and red background and extra field displayed for the Employee compared to the manager

Upvotes: 10

Greg D
Greg D

Reputation: 44096

1) Create your two different data templates, just as you say you've already done. 2) Create a custom DataTemplateSelector to choose the appropriate template.

One of your comments states that you're getting an error from your DataTemplateSelector. Verify that you're implementing the class correctly, perhaps paste your implementation. It should be fairly small and straightforward.

Upvotes: 1

treehouse
treehouse

Reputation: 2531

Just define two different DataTemplates in the Resources section, one for each RuleCondition type.

Upvotes: 2

Related Questions