C# 具有多个数据模板的ItemsControl
我有一个ItemsControl,画布为C# 具有多个数据模板的ItemsControl,c#,wpf,xaml,itemscontrol,C#,Wpf,Xaml,Itemscontrol,我有一个ItemsControl,画布为ItemsPanelTemplate和多个DataTemplates,如下所示: <ItemsControl ItemsSource="{Binding Path=DisplayObjects}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas />
ItemsPanelTemplate
和多个DataTemplates
,如下所示:
<ItemsControl ItemsSource="{Binding Path=DisplayObjects}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type viewModels:Object1ViewModel}">
<views:Object1UIElement/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:Object2ViewModel}">
<viewModels:Object2UIElement/>
</DataTemplate>
</ItemsControl.Resources >
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=X"/>
<Setter Property="Canvas.Top" Value="{Binding Path=Y"/>
<!-- Serveral more properties that are either attached to the Canvas or UIElement -->
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
两个viewmodels位置(X,Y)绑定到画布左侧和顶部属性。问题是我想以不同的方式将viewModels属性绑定到画布
例如,Object1ViewModel
使用一个多绑定转换器,该转换器根据ItemControl的大小等因素返回一个值,其中Object2ViewModel
应直接绑定到画布左/顶属性,如上图所示
我已经尝试直接在DataTemplate中设置绑定,以便可以为不同的DataTemplates设置不同的绑定样式,但这不起作用。。对象将无法找到画布,因为它们是在ContentPresenter中创建的。听起来您需要一个
或者类似的东西。所以我通过克莱门斯的评论找到了答案。正如他提到的,我需要一个ItemContainerStyleSelector,因此我创建了一个类,该类将为我提供适当的样式:
public class MyItemContainerStyleSelector : StyleSelector
{
public override Style SelectStyle(object item, DependencyObject container)
{
var element = container as FrameworkElement; // this will be a ContentPresenter
if (element == null) return null;
var viewModel = element.DataContext;
if (viewModel is Object1ViewModel)
{
return element.FindResource("Object1Style") as Style;
}
if (viewModel is Object2ViewModel)
{
return element.FindResource("Object2Style") as Style;
}
return null;
}
}
在xaml中,我将在参考资料中定义样式,并将ItemContainerStyleSelector
设置为我的新样式选择器:
<UserControl.Resources>
<utilities:MyItemContainerStyleSelector x:Key="MyStyleSelector"/>
<Style x:Key="Object1Style" TargetType="ContentPresenter">
...
</Style>
<Style x:Key="Object2Style" TargetType="ContentPresenter">
...
</Style>
</UserControl.Resources>
<ItemsControl
...
ItemContainerStyleSelector="{StaticResource MyStyleSelector}" >
</ItemsControl>
...
...
执行此操作时,不得设置属性
ItemContainerStyle
,否则将忽略样式选择器。听起来您需要两种不同的ItemContainerStyle。您可以将ItemsControl的属性设置为适当的样式选择器。@Clemens谢谢,我通过您的评论解决了这个问题,并发布了我的实现。
<UserControl.Resources>
<utilities:MyItemContainerStyleSelector x:Key="MyStyleSelector"/>
<Style x:Key="Object1Style" TargetType="ContentPresenter">
...
</Style>
<Style x:Key="Object2Style" TargetType="ContentPresenter">
...
</Style>
</UserControl.Resources>
<ItemsControl
...
ItemContainerStyleSelector="{StaticResource MyStyleSelector}" >
</ItemsControl>