看,你太复杂了。您所需要的只是一个 ObservableCollection,它可以保存您的所有项目和每个项目的适当 DataTemplate。不需要 DataTemplateSelectors 或任何其他类似的东西。point directly back to the ObservableCollection
此外,无论这意味着什么,都没有必要:
主窗口:
<Window x:Class="WpfApplication5.Window3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication5"
Title="Window3" Height="300" Width="300">
<Window.Resources>
<DataTemplate DataType="{x:Type local:Item1}">
<local:UserControl1/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Item2}">
<local:UserControl2/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Item3}">
<local:UserControl3/>
</DataTemplate>
</Window.Resources>
<ListBox ItemsSource="{Binding}"/>
</Window>
代码背后:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.ComponentModel;
namespace WpfApplication5
{
public partial class Window3 : Window
{
public Window3()
{
InitializeComponent();
DataContext = new ObservableCollection<ItemBase>
{
new Item1() {MyText1 = "This is MyText1 inside an Item1"},
new Item2() {MyText2 = "This is MyText2 inside an Item2"},
new Item3() {MyText3 = "This is MyText3 inside an Item3", MyBool = true}
};
}
}
public class ItemBase: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChange(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Item1: ItemBase
{
private string _myText1;
public string MyText1
{
get { return _myText1; }
set
{
_myText1 = value;
NotifyPropertyChange("MyText1");
}
}
}
public class Item2: ItemBase
{
private string _myText2;
public string MyText2
{
get { return _myText2; }
set
{
_myText2 = value;
NotifyPropertyChange("MyText2");
}
}
private ObservableCollection<string> _options;
public ObservableCollection<string> Options
{
get { return _options ?? (_options = new ObservableCollection<string>()); }
}
public Item2()
{
Options.Add("Option1");
Options.Add("Option2");
Options.Add("Option3");
Options.Add("Option4");
}
}
public class Item3: ItemBase
{
private string _myText3;
public string MyText3
{
get { return _myText3; }
set
{
_myText3 = value;
NotifyPropertyChange("MyText3");
}
}
private bool _myBool;
public bool MyBool
{
get { return _myBool; }
set
{
_myBool = value;
NotifyPropertyChange("MyBool");
}
}
}
}
用户控件1:
<UserControl x:Class="WpfApplication5.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Border BorderBrush="Black" BorderThickness="1">
<StackPanel>
<TextBlock Text="This is UserControl1"/>
<TextBlock Text="{Binding MyText1}"/>
</StackPanel>
</Border>
</UserControl>
用户控件2:
<UserControl x:Class="WpfApplication5.UserControl2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Border BorderBrush="Black" BorderThickness="1">
<StackPanel>
<TextBlock Text="This is UserControl2"/>
<TextBox Text="{Binding MyText2}"/>
<ComboBox ItemsSource="{Binding Options}" SelectedItem="{Binding MyText2}"/>
</StackPanel>
</Border>
</UserControl>
用户控件3:
<UserControl x:Class="WpfApplication5.UserControl3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Border BorderBrush="Black" BorderThickness="1">
<StackPanel>
<TextBlock Text="This is UserControl3"/>
<TextBlock Text="{Binding MyText3}"/>
<CheckBox Content="This is the MyBool Property" IsChecked="{Binding MyBool}"/>
</StackPanel>
</Border>
</UserControl>
只需将我的代码复制并粘贴到文件 - 新建 - WPF 应用程序中,然后自己查看结果。它看起来像这样: