Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有多个数据模板的ItemsControl_C#_Wpf_Xaml_Itemscontrol - Fatal编程技术网

C# 具有多个数据模板的ItemsControl

C# 具有多个数据模板的ItemsControl,c#,wpf,xaml,itemscontrol,C#,Wpf,Xaml,Itemscontrol,我有一个ItemsControl,画布为ItemsPanelTemplate和多个DataTemplates,如下所示: <ItemsControl ItemsSource="{Binding Path=DisplayObjects}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas />

我有一个ItemsControl,画布为
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>