[英]Select ItemTemplate in value converter
我試圖在基於每個項目屬性的列表視圖中有多個ItemTemplates。 但是我在值轉換器中不斷收到{“對COM組件的調用已返回錯誤HRESULT E_FAIL。”}:
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>
有什么想法可以解決這個問題嗎?
通常的方法是編寫一個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;
}
}
但是我在值轉換器中不斷收到{“對COM組件的調用已返回錯誤HRESULT E_FAIL。”}。
當對樣式或事件處理程序的引用不存在或不在XAML上下文中時,通常會發生此錯誤。
您僅發布了轉換器的代碼和xaml代碼的一部分,我無法100%復制數據模型和xaml,但是從您的代碼中,我認為在轉換器中,您想返回特定的DataTemplate
,但是您實際上返回了一個KeyValuePair<object, object>
,資源在ResourceDictionary中定義,並遵循“鍵值”部分,有關更多信息,您可以參考ResourceDictionary和XAML資源引用 。
在這里,我寫了一個示例,再次我沒有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屬性 ,因此我只將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
是完成這項工作的更常見方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.