我试图在listview中根据每个items属性设置多个ItemTemplates。但我继续得到{"错误HRESULT E_FAIL已从调用COM组件返回。"}在我的值转换器中:
public class EquipmentTemplateConverter : IValueConverter
{
public object Convert(object value, Type type, object parameter, string language)
{
switch ((EquipmentType) (int) value)
{
case EquipmentType.Normal:
return Application.Current.Resources.FirstOrDefault(r => r.Key.ToString() == "EquipmentNormalTemplate");
case EquipmentType.Upgrade:
return Application.Current.Resources.FirstOrDefault(r => r.Key.ToString() == "EquipmentUpgradeTemplate");
default:
throw new ArgumentOutOfRangeException(nameof(value), value, null);
}
}
public object ConvertBack(object value, Type type, object parameter, string language)
{
throw new NotImplementedException();
}
}
XAML:
<DataTemplate x:Key="EquipmentTemplate" >
<Grid>
<ContentControl DataContext="{Binding}" Content="{Binding}" x:Name="TheContentControl" ContentTemplate="{Binding Equipment.Type, Converter={StaticResource EquipmentTemplateConverter } }" />
</Grid>
</DataTemplate>
我有什么想法可以解决这个问题吗?
答案 0 :(得分:1)
通常的方法是编写DataTemplateSelector
并将其实例分配给ContentControl.ContentTemplateSelector
。
<DataTemplate x:Key="EquipmentTemplate" >
<DataTemplate.Resources>
<local:EquipmentTemplateSelector x:Key="EquipmentTemplateSelector" />
</DataTemplate.Resources>
<Grid>
<ContentControl
DataContext="{Binding}"
Content="{Binding}"
x:Name="TheContentControl"
ContentTemplateSelector="{StaticResource EquipmentTemplateSelector}"
/>
</Grid>
</DataTemplate>
C#:
public class EquipmentTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
// container is the container. Cast it to something you can call
// FindResource() on. Put in a breakpoint and use the watch window.
// I'm at work with Windows 7. Shouldn't be too hard.
var whatever = container as SomethingOrOther;
Object resKey = null;
// ************************************
// Do stuff here to pick a resource key
// ************************************
// Application.Current.Resources is ONE resource dictionary.
// Use FindResource to find any resource in scope.
return whatever.FindResource(resKey) as DataTemplate;
}
}
答案 1 :(得分:0)
但我一直得到{“错误HRESULT E_FAIL已从调用COM组件返回。”}在我的值转换器中。
当对样式或事件处理程序的引用不存在或不在XAML的上下文中时,通常会发生此错误。
您只发布了转换器的代码和部分xaml代码,我无法100%重现您的数据模型和您的xaml,但是从您的代码中,我认为在您的转换器中,您希望返回具体的DataTemplate
,但实际上您返回KeyValuePair<object, object>
,资源在ResourceDictionary中定义,请点击“键值”部分,有关详细信息,请参阅ResourceDictionary and XAML resource references。< / p>
在这里我写了一个样本,我再没有100%重现你的xaml和数据模型:
MainPage.xaml中:
<Page.Resources>
<local:EquipmentTemplateConverter x:Key="EquipmentTemplateConverter" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{x:Bind list}">
<ListView.ItemTemplate>
<DataTemplate>
<ContentControl DataContext="{Binding}" Content="{Binding}" ContentTemplate="{Binding Count, Converter={StaticResource EquipmentTemplateConverter}}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
代码背后的代码:
private ObservableCollection<EquipmentType> list = new ObservableCollection<EquipmentType>();
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
list.Add(new EquipmentType { Count = 0 });
list.Add(new EquipmentType { Count = 1 });
list.Add(new EquipmentType { Count = 0 });
list.Add(new EquipmentType { Count = 0 });
list.Add(new EquipmentType { Count = 1 });
list.Add(new EquipmentType { Count = 1 });
}
我的EquipmentType
课很简单:
public class EquipmentType
{
public int Count { get; set; }
}
和EquipmentTemplateConverter
是这样的:
public class EquipmentTemplateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
switch ((int)value)
{
case 0:
var a = Application.Current.Resources.FirstOrDefault(r => r.Key.ToString() == "EquipmentNormalTemplate");
return a.Value;
case 1:
var b = Application.Current.Resources.FirstOrDefault(r => r.Key.ToString() == "EquipmentUpgradeTemplate");
return b.Value;
default:
throw new ArgumentOutOfRangeException(nameof(value), value, null);
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
由于您在转换器中使用Application.Resources property,我只需将DataTemplate
放入App.xaml进行测试:
<Application.Resources>
<DataTemplate x:Key="EquipmentNormalTemplate">
<Grid>
<TextBlock Text="This is EquipmentNormalTemplate." />
</Grid>
</DataTemplate>
<DataTemplate x:Key="EquipmentUpgradeTemplate">
<Grid>
<TextBlock Text="This is EquipmentUpgradeTemplate." />
</Grid>
</DataTemplate>
</Application.Resources>
但我同意@Ed Plunkett,使用DataTemplateSelector
是一种更常用的方式来完成这项工作。