问题
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 ObservableCollection
s?
回答1:
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
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
回答2:
Just define two different DataTemplates in the Resources section, one for each RuleCondition type.
回答3:
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.
来源:https://stackoverflow.com/questions/15696467/wpf-and-observablecollectiont