Xaml ults.First()值; } 抛出新的AmbigiousResolveTemplateFound(item.GetType(),results.Select(x=>x.Key)); } else if(results.Length==1){ 返回结果[0]。值; } 返回默认模板; } #区域优先属性 公共静态只读从属属性PriorityProperty= DependencyProperty.RegisterAttached( “优先权”, 类型(int), 类型(InterfaceAwareTemplateSelector), 新属性元数据(0); 公共静态int GetPriority(DependencyObject项){ 如果(item==null){抛出新的ArgumentNullException(“item”);} return(int)item.GetValue(PriorityProperty); } 公共静态void SetPriority(DependencyObject项,int值){ 如果(item==null){抛出新的ArgumentNullException(“item”);} 项.设置值(优先属性,值); } 公共静态bool IsPrioritySet(DependencyObject项){ 如果(item==null){抛出新的ArgumentNullException(“item”);} var结果=item.ReadLocalValue(PriorityProperty); 返回结果!=DependencyProperty.UnsetValue; } #端区 }
希望有人会觉得这个实现很有帮助。再次感谢菲利普和杰瑞的帮助。是的,改用打字是故事的一个要点。我不能实际使用字符串而不是类型,因为除非我有一个完全限定的字符串,否则我将无法基于字符串构造类型。请检查我的编辑。我认为您无法在XAML中直接使用类型。在XAML中使用类型名称,或者在代码隐藏中使用开关块和接受类型的列表,或者使用反射来查找与字符串值匹配的类型。是的,这就是我作为解决方案的中间步骤所做的。我也无法在XAML中进行字符串->类型转换:/Thanway感谢您的提示老实说,我认为这可能就是您的解决方案。Xaml ults.First()值; } 抛出新的AmbigiousResolveTemplateFound(item.GetType(),results.Select(x=>x.Key)); } else if(results.Length==1){ 返回结果[0]。值; } 返回默认模板; } #区域优先属性 公共静态只读从属属性PriorityProperty= DependencyProperty.RegisterAttached( “优先权”, 类型(int), 类型(InterfaceAwareTemplateSelector), 新属性元数据(0); 公共静态int GetPriority(DependencyObject项){ 如果(item==null){抛出新的ArgumentNullException(“item”);} return(int)item.GetValue(PriorityProperty); } 公共静态void SetPriority(DependencyObject项,int值){ 如果(item==null){抛出新的ArgumentNullException(“item”);} 项.设置值(优先属性,值); } 公共静态bool IsPrioritySet(DependencyObject项){ 如果(item==null){抛出新的ArgumentNullException(“item”);} var结果=item.ReadLocalValue(PriorityProperty); 返回结果!=DependencyProperty.UnsetValue; } #端区 },xaml,c#-4.0,windows-runtime,winrt-xaml,Xaml,C# 4.0,Windows Runtime,Winrt Xaml,希望有人会觉得这个实现很有帮助。再次感谢菲利普和杰瑞的帮助。是的,改用打字是故事的一个要点。我不能实际使用字符串而不是类型,因为除非我有一个完全限定的字符串,否则我将无法基于字符串构造类型。请检查我的编辑。我认为您无法在XAML中直接使用类型。在XAML中使用类型名称,或者在代码隐藏中使用开关块和接受类型的列表,或者使用反射来查找与字符串值匹配的类型。是的,这就是我作为解决方案的中间步骤所做的。我也无法在XAML中进行字符串->类型转换:/Thanway感谢您的提示老实说,我认为这可能就是您的解
<ListView Grid.Column="0"
ItemsSource="{Binding Media}"
SelectionMode="None">
<ListView.ItemTemplateSelector>
<selectors:InterfaceAwareTemplateSelector>
<DataTemplate x:Key="IMedia">
<Image Source="{Binding PreviewImage}" />
</DataTemplate>
<DataTemplate x:Key="IDocument">
<TextBlock Text="test" />
</DataTemplate>
</selectors:InterfaceAwareTemplateSelector>
</ListView.ItemTemplateSelector>
</ListView>
[ContentProperty(Name = "Items")]
public class InterfaceAwareTemplateSelector: DataTemplateSelector {
public DataTemplate DefaultTemplate { get; set; }
public Dictionary<Type, DataTemplate> Items { get; set; }
public InterfaceAwareTemplateSelector() {
Items = new Dictionary<Type, DataTemplate>();
}
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var result = (
from t in Items
where t.Key.GetTypeInfo().IsAssignableFrom(item.GetType().GetTypeInfo())
select t.Value).FirstOrDefault();
return result ?? DefaultTemplate;
}
}
A first chance exception of type 'Windows.UI.Xaml.Markup.XamlParseException' occurred in Hicron.ProductCatalog.MainUI.exe
WinRT information: E_UNKNOWN_ERROR [Line: 47 Position: 39]
An exception of type 'Windows.UI.Xaml.Markup.XamlParseException' occurred in Hicron.ProductCatalog.MainUI.exe but was not handled in user code
WinRT information: E_UNKNOWN_ERROR [Line: 47 Position: 39]
Additional information: Unspecified error
[ContentProperty(Name = "Items")]
public class InterfaceAwareTemplateSelector: DataTemplateSelector {
public DataTemplate DefaultTemplate { get; set; }
public List<InterfaceAwareTemplateSelectorItem> Items { get; set; }
public InterfaceAwareTemplateSelector() {
Items = new List<InterfaceAwareTemplateSelectorItem>();
}
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) {
if (item == null) {
return DefaultTemplate;
}
var result = (
from t in Items
where t.Type.GetTypeInfo().IsAssignableFrom(item.GetType().GetTypeInfo())
select t.Template).FirstOrDefault();
return result ?? DefaultTemplate;
}
}
public class InterfaceAwareTemplateSelectorItem
{
public Type Type { get; set; }
public DataTemplate Template { get; set; }
}
// somewhere in page tag
xmlns:bo="using:/*long long namespace*/.BusinessObjects"
// somewhere in XAML file
<ListView Grid.Column="0"
ItemsSource="{Binding Media}"
SelectionMode="None">
<ListView.ItemTemplateSelector>
<selectors:InterfaceAwareTemplateSelector>
<selectors:InterfaceAwareTemplateSelectorItem Type="bo:IMedia">
<selectors:InterfaceAwareTemplateSelectorItem.Template>
<DataTemplate>
<Image Source="{Binding PreviewImage}"
Tapped="ImageTapped" />
</DataTemplate>
</selectors:InterfaceAwareTemplateSelectorItem.Template>
</selectors:InterfaceAwareTemplateSelectorItem>
<selectors:InterfaceAwareTemplateSelectorItem Type="bo:IDocument">
<selectors:InterfaceAwareTemplateSelectorItem.Template>
<DataTemplate>
<TextBlock Text="pa8u4mrapwu" />
</DataTemplate>
</selectors:InterfaceAwareTemplateSelectorItem.Template>
</selectors:InterfaceAwareTemplateSelectorItem>
</selectors:InterfaceAwareTemplateSelector>
</ListView.ItemTemplateSelector>
</ListView>
public interface IFake1 { }
public interface IFake2 { }
public class TemplateItem
{
public DataTemplate Template { get; set; }
public string Interface { get; set; }
}
public class MySelector : DataTemplateSelector
{
public List<TemplateItem> Templates { get; set; }
}
<GridView>
<GridView.ItemTemplateSelector>
<local:MySelector>
<local:MySelector.Templates>
<local:TemplateItem Interface="IFake1">
<local:TemplateItem.Template>
<DataTemplate>
<!-- TODO -->
</DataTemplate>
</local:TemplateItem.Template>
</local:TemplateItem>
<local:TemplateItem Interface="IFake2">
<local:TemplateItem.Template>
<DataTemplate>
<!-- TODO -->
</DataTemplate>
</local:TemplateItem.Template>
</local:TemplateItem>
</local:MySelector.Templates>
</local:MySelector>
</GridView.ItemTemplateSelector>
</GridView>
<ListView Grid.Column="0"
ItemsSource="{Binding Media}"
SelectionMode="None">
<ListView.ItemTemplateSelector>
<selectors:InterfaceAwareTemplateSelector>
<DataTemplate x:Key="IMedia">
<Image Source="{Binding PreviewImage}" Tapped="ImageTapped"/>
</DataTemplate>
<DataTemplate x:Key="IDocument">
<commonItems:DocumentItemPresenter TappedCommand="{Binding DataContext.OpenDocument, ElementName=PageRoot}"/>
</DataTemplate>
</selectors:InterfaceAwareTemplateSelector>
</ListView.ItemTemplateSelector>
</ListView>
[ContentProperty(Name = "Items")]
public class InterfaceAwareTemplateSelector: DataTemplateSelector {
public DataTemplate DefaultTemplate { get; set; }
public Dictionary<string, DataTemplate> Items { get; set; }
public InterfaceAwareTemplateSelector() {
Items = new Dictionary<string, DataTemplate>();
}
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) {
if (item == null) {
return DefaultTemplate;
}
var result = (
from ii in item.GetType().GetTypeInfo().ImplementedInterfaces
from dt in Items
where ii.Name == dt.Key
select dt.Value).FirstOrDefault();
return result ?? DefaultTemplate;
}
}
<GridView ....>
<GridView.ItemTemplateSelector>
<selectors:InterfaceAwareTemplateSelector>
<!-- ReSharper disable once Xaml.RedundantResource -->
<DataTemplate x:Key="INewsContainer" selectors:InterfaceAwareTemplateSelector.Priority="1">
<ctrls:ItemsContainerTile Width="350" Height="350"
ItemTappedCommand="{Binding DataContext.OpenNewsDetails, ElementName=PageRoot}"/>
</DataTemplate>
<!-- ReSharper disable once Xaml.RedundantResource -->
<DataTemplate x:Key="ISimpleMaterial" selectors:InterfaceAwareTemplateSelector.Priority="0">
<ctrls:GenericTile Width="350" Height="350"
TappedCommand="{Binding DataContext.OpenDetails, ElementName=PageRoot}" />
</DataTemplate>
</selectors:InterfaceAwareTemplateSelector>
</GridView.ItemTemplateSelector>
.... the rest of XAML
[ContentProperty(Name = "Items")]
public class InterfaceAwareTemplateSelector: DataTemplateSelector {
public DataTemplate DefaultTemplate { get; set; }
public Dictionary<string, DataTemplate> Items { get; set; }
public InterfaceAwareTemplateSelector() {
Items = new Dictionary<string, DataTemplate>();
}
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) {
if (item == null) {
return DefaultTemplate;
}
var results = (
from ii in item.GetType().GetTypeInfo().ImplementedInterfaces
from dt in Items
where ii.Name == dt.Key
select dt)
.ToArray();
if (results.Length > 1) {
var orderedResults =
from r in results
where IsPrioritySet(r.Value)
orderby GetPriority(r.Value) descending
select r;
if (orderedResults.Any()) {
return orderedResults.First().Value;
}
throw new AmbigiousResolveTemplateFound(item.GetType(), results.Select(x => x.Key));
}
else if (results.Length == 1) {
return results[0].Value;
}
return DefaultTemplate;
}
#region PriorityProperty
public static readonly DependencyProperty PriorityProperty =
DependencyProperty.RegisterAttached(
"Priority",
typeof(int),
typeof(InterfaceAwareTemplateSelector),
new PropertyMetadata(0));
public static int GetPriority(DependencyObject item) {
if (item == null) { throw new ArgumentNullException("item"); }
return (int)item.GetValue(PriorityProperty);
}
public static void SetPriority(DependencyObject item, int value) {
if (item == null) { throw new ArgumentNullException("item"); }
item.SetValue(PriorityProperty, value);
}
public static bool IsPrioritySet(DependencyObject item) {
if (item == null) { throw new ArgumentNullException("item"); }
var result = item.ReadLocalValue(PriorityProperty);
return result != DependencyProperty.UnsetValue;
}
#endregion
}