对于我的应用程序,我有一个ItemsControl,它具有第一个项目的不同模板(简称为Template2),以及其余项目的默认模板(Template1)。我使用以下XAML完成了这项工作:
<DataTemplate x:Key="MyDataTemplate">
<ContentPresenter x:Name="TemplateContentPresenter"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"
ContentTemplate="{StaticResource Template1}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},
Converter= {StaticResource IsFirstItemInCollectionConverter}}"
Value="True">
<Setter TargetName="TemplateContentPresenter"
Property="ContentTemplate"
Value="{StaticResource Template2}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
IsFirstItemInCollectionConverter的代码如下:
public class IsFirstItemInCollectionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DependencyObject item = (DependencyObject)value;
ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);
Console.WriteLine("converted");
return (ic.ItemContainerGenerator.IndexFromContainer(item) == 0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
问题是当我在itemsControl的itemssource中进行更改时,我的绑定不会更新。 (在显示itemsControl的视图中,我有可以添加和删除项目的按钮)。只有在切换视图并重新加载视图后,绑定才会更新并显示正确的模板。我该如何纠正这种行为?我假设我必须将UpdateSourceTrigger设置为显式并手动更新源,但我不知道如何在datatemplate中执行此操作。在此先感谢您的帮助。
答案 0 :(得分:2)
您已在Binding="{Binding RelativeSource={RelativeSource Self}
上触发了DataTrigger,当ListBoxItem的datacontext发生更改时,它将被触发。
我建议在这里使用DataTemplateSelector作为项目控件,并为其设置ItemTemplateSelector
属性。在SelectTemplate方法中,您可以根据任何逻辑返回新添加项目的模板:
TemplateSelector:
public class MyTemplateSelector : DataTemplateSelector
{
public DataTemplate FirstItemTemplate { get; set; }
public DataTemplate DefaultItemTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
//Logic to return first or default template comes here
}
}
在xaml:
<local:MyTemplateSelector x:Key="myTemplate">
<local:MyTemplateSelector.FirstItemTemplate>
<!--First Template-->
</local:MyTemplateSelector.FirstItemTemplate>
<local:MyTemplateSelector.DefaultItemTemplate>
<!--Default Template-->
</local:MyTemplateSelector.DefaultItemTemplate>
</local:MyTemplateSelector>
<强>更新强>
对于您的特定情况,如果您未在itemsControl中使用交替,您也可以像下面一样解决此问题。您可以将AlternationCount用于ListBox并绑定到每个ListboxItem的ItemsControl.AlternationIndex。因此,每当列表框交替索引发生更改时,您都可以更改其模板:
XAML:
<ListBox AlternationCount="{Binding Items.Count, RelativeSource={RelativeSource Self}}" x:Name="itemControl" ItemsSource="{Binding Items}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template" Value="{StaticResource DefaultTemplate}" />
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Template" Value="{StaticResource FirstTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
这里的DefaultTemplate和FirstTemplate是controlTemplates。
我尝试了它,每当我删除索引0处的项目时,它都适用于我,它为下一个项目提供了第一个项目模板。
希望它适合你。
谢谢,
答案 1 :(得分:0)
好的,我修好了但是态度不雅。我暂时将绑定项设置为null,以便每次删除/添加项时强制DataTemplateSelector重新评估。