用户控件的数据模板选择器
DataTemplateSelector for UserControl
我有一个列表框,我想在 UWP 应用程序中加载不同类型的用户控件。
我需要 UserControls 的原因是因为列表中显示的每个项目都需要代码隐藏,所以简单的 DataTemplate 无法解决问题。
我在行
上遇到错误
<converters:HomeWidgetControlPicker>
在列表框中。
The specified value cannot be assigned. The following type was expected: "DependencyObject".
如何加载 UserControl?我在一个旧的 UWP 应用程序中使用了这个方法并且它在那里工作,但在我的新项目中它没有。
我不能使用 x:DataType,因为所有项目都是相同的 class (HomeWidget),但是根据 HomeWidget 的类型 属性 选择了正确的 UserControl。
我做了一个DataTemplateSelector:
public class HomeWidgetControlPicker : DataTemplateSelector
{
public DataTemplate Artist { get; set; }
public DataTemplate Release { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if (item != null)
{
var result = (HomeWidget)item;
if (result.Type == "artist")
{
return Artist;
}
if (result.Type == "release")
{
return Release;
}
}
return null;
}
}
我有一个列表框,目前只使用类型 (HomeWidgetControlPicker.Artist),但以后会更多。
<ListBox x:Name="wrapGrid" ItemContainerStyle="{StaticResource WrapPanelBorderedItem}" ItemsSource="{x:Bind WidgetList}" Background="{x:Null}" ScrollViewer.VerticalScrollBarVisibility="Disabled" VerticalAlignment="Top" HorizontalAlignment="Center" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<userControls:WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<converters:HomeWidgetControlPicker>
<converters:HomeWidgetControlPicker.Artist>
<DataTemplate>
<homeItems:HomeArtist></homeItems:HomeArtist>
</DataTemplate>
</converters:HomeWidgetControlPicker.Artist>
</converters:HomeWidgetControlPicker>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
你使用DataTemplateSelector
的方式应该是错误的。在您的代码片段中,DataTemplateSelector
被放置为 DataTemplateSelector
class 的 DataTemplate
, but actually, you can use a DataTemplateSelector
and set properties such as ItemTemplateSelector
to assign it to a data view. See remarks section 的根元素以获取更多详细信息。
The base DataTemplateSelector class is not used as an object element in XAML. However, it is a common scenario to derive a custom DataTemplateSelector, map a xmlns prefix for the custom class and its namespace/assembly, and then refer to an instance of the custom class as defined in a Resources block in XAML. This makes it possible to refer to the custom template selector class by x:Key, and use that reference to set the value of properties such as ItemTemplateSelector in XAML templates and visual states.
例如:
<Page.Resources>
<DataTemplate x:Key="Artist" x:DataType="local:HomeWidget">
<Grid>
<local:UserControl1></local:UserControl1>
...
</Grid>
</DataTemplate>
<DataTemplate x:Key="Release" x:DataType="local:HomeWidget">
<Grid>
<local:UserControl2></local:UserControl2>
...
</Grid>
</DataTemplate>
<local:HomeWidgetControlPicker x:Key="HomeWidgetControlPicker" Artist="{StaticResource Artist}" Release="{StaticResource Release}">
</local:HomeWidgetControlPicker>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListBox x:Name="wrapGrid" ItemTemplateSelector="{StaticResource HomeWidgetControlPicker}" ItemsSource="{x:Bind WidgetList}"
...
</ListBox>
</Grid>
我有一个列表框,我想在 UWP 应用程序中加载不同类型的用户控件。
我需要 UserControls 的原因是因为列表中显示的每个项目都需要代码隐藏,所以简单的 DataTemplate 无法解决问题。
我在行
上遇到错误<converters:HomeWidgetControlPicker>
在列表框中。
The specified value cannot be assigned. The following type was expected: "DependencyObject".
如何加载 UserControl?我在一个旧的 UWP 应用程序中使用了这个方法并且它在那里工作,但在我的新项目中它没有。
我不能使用 x:DataType,因为所有项目都是相同的 class (HomeWidget),但是根据 HomeWidget 的类型 属性 选择了正确的 UserControl。
我做了一个DataTemplateSelector:
public class HomeWidgetControlPicker : DataTemplateSelector
{
public DataTemplate Artist { get; set; }
public DataTemplate Release { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if (item != null)
{
var result = (HomeWidget)item;
if (result.Type == "artist")
{
return Artist;
}
if (result.Type == "release")
{
return Release;
}
}
return null;
}
}
我有一个列表框,目前只使用类型 (HomeWidgetControlPicker.Artist),但以后会更多。
<ListBox x:Name="wrapGrid" ItemContainerStyle="{StaticResource WrapPanelBorderedItem}" ItemsSource="{x:Bind WidgetList}" Background="{x:Null}" ScrollViewer.VerticalScrollBarVisibility="Disabled" VerticalAlignment="Top" HorizontalAlignment="Center" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<userControls:WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<converters:HomeWidgetControlPicker>
<converters:HomeWidgetControlPicker.Artist>
<DataTemplate>
<homeItems:HomeArtist></homeItems:HomeArtist>
</DataTemplate>
</converters:HomeWidgetControlPicker.Artist>
</converters:HomeWidgetControlPicker>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
你使用DataTemplateSelector
的方式应该是错误的。在您的代码片段中,DataTemplateSelector
被放置为 DataTemplateSelector
class 的 DataTemplate
, but actually, you can use a DataTemplateSelector
and set properties such as ItemTemplateSelector
to assign it to a data view. See remarks section 的根元素以获取更多详细信息。
The base DataTemplateSelector class is not used as an object element in XAML. However, it is a common scenario to derive a custom DataTemplateSelector, map a xmlns prefix for the custom class and its namespace/assembly, and then refer to an instance of the custom class as defined in a Resources block in XAML. This makes it possible to refer to the custom template selector class by x:Key, and use that reference to set the value of properties such as ItemTemplateSelector in XAML templates and visual states.
例如:
<Page.Resources>
<DataTemplate x:Key="Artist" x:DataType="local:HomeWidget">
<Grid>
<local:UserControl1></local:UserControl1>
...
</Grid>
</DataTemplate>
<DataTemplate x:Key="Release" x:DataType="local:HomeWidget">
<Grid>
<local:UserControl2></local:UserControl2>
...
</Grid>
</DataTemplate>
<local:HomeWidgetControlPicker x:Key="HomeWidgetControlPicker" Artist="{StaticResource Artist}" Release="{StaticResource Release}">
</local:HomeWidgetControlPicker>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListBox x:Name="wrapGrid" ItemTemplateSelector="{StaticResource HomeWidgetControlPicker}" ItemsSource="{x:Bind WidgetList}"
...
</ListBox>
</Grid>