C# ContentPresenter而不是UserControl被添加到我的自定义面板中

C# ContentPresenter而不是UserControl被添加到我的自定义面板中,c#,wpf,custom-controls,itemscontrol,C#,Wpf,Custom Controls,Itemscontrol,我创建了一个从画布继承的自定义面板。我想使用它在ItemsControl中查看我的用户控件 这是我的XAML: <ItemsControl ItemsSource="{Binding Groups}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <c:MyCustomPanel /> </Item

我创建了一个从画布继承的自定义面板。我想使用它在ItemsControl中查看我的用户控件

这是我的XAML:

<ItemsControl ItemsSource="{Binding Groups}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <c:MyCustomPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <ItemContainerTemplate>
                <app:MyUserControl Margin="5" MinWidth="200"/>                    
            </ItemContainerTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
问题在于,出于某种原因,InternalChildren由ContentPresenter项而不是我的用户控件组成。当然,在每个ContentPresenter中都有我的用户控制,但这不是我想要的。我需要在这里读取userControl的MinWidth,但我从ContentPresenter(始终为0)读取它

当我做非常简单的测试时:

<ItemsControl ItemsSource="{Binding Buttons}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <c:MyCustomPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>


按钮只是按钮控件的列表,一切按预期进行。所以我认为问题可能出在如何使用ItemsControl上。但是不知道如何修复它。

在ItemContainerStyle中设置ContentPresenter的MinWidth属性:

<ItemsControl ItemsSource="{Binding Groups}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <c:MyCustomPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <app:MyUserControl Margin="5"/>                    
        </DataTemplate>
    </ItemsControl.ItemTemplate>

    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="MinWidth" Value="200"/>                    
        </Style >
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

在ItemContainerStyle中设置ContentPresenter的MinWidth属性:

<ItemsControl ItemsSource="{Binding Groups}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <c:MyCustomPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <app:MyUserControl Margin="5"/>                    
        </DataTemplate>
    </ItemsControl.ItemTemplate>

    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="MinWidth" Value="200"/>                    
        </Style >
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

问题在于,出于某种原因,InternalChildren由ContentPresenter项而不是我的用户控件组成

这是因为
ItemsControl
将所有项目包装在
ContentPresenter
中,除非它们是
UIElements
。如果绑定到
ui元素的集合
,例如
按钮
,则不会创建
ContentPresenter
,但也不会应用
ItemTemplate

您可以按照@Clemens的建议设置
ContentPresenter
容器的
MinWidth
,也可以通过实现自己的自定义
ItemsControl
并覆盖
GetContainerForItemOverride()
IsItemItsOwnContainerOverride()
方法:

public class MyItemsControl : System.Windows.Controls.ItemsControl
{
    protected virtual DependencyObject GetContainerForItemOverride()
    {
        return new MyUserControl();
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return (item is MyUserControl);
    }
}
问题在于,出于某种原因,InternalChildren由ContentPresenter项而不是我的用户控件组成

这是因为
ItemsControl
将所有项目包装在
ContentPresenter
中,除非它们是
UIElements
。如果绑定到
ui元素的集合
,例如
按钮
,则不会创建
ContentPresenter
,但也不会应用
ItemTemplate

您可以按照@Clemens的建议设置
ContentPresenter
容器的
MinWidth
,也可以通过实现自己的自定义
ItemsControl
并覆盖
GetContainerForItemOverride()
IsItemItsOwnContainerOverride()
方法:

public class MyItemsControl : System.Windows.Controls.ItemsControl
{
    protected virtual DependencyObject GetContainerForItemOverride()
    {
        return new MyUserControl();
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return (item is MyUserControl);
    }
}

ItemsControl
将所有项目包装在一个
ContentPresenter
中。那么为什么在示例中使用按钮而不是CP?因为没有创建
ContentPresenter
,也没有任何
itemstemplate
应用于
UIElements
按钮,只有那些不是UIElements的项目才会包装在ContentPresenter中。因此,如果将按钮集合指定给ItemsSource属性,则它们不会被包装,而是直接添加到ItemsPanel。将
MyUserControl
添加为
MyCustomPanel
的直接子级的唯一方法是创建一个派生ItemsControl,并覆盖
GetContainerForItemOverride
IsItemItsOwnContainerOverride
方法。
ItemsControl
将所有项目包装在
ContentPresenter
。那么,为什么在示例中使用按钮时,我得到的是按钮而不是CP?因为没有创建
ContentPresenter
,也没有为
UIElements
应用任何
ItemTemplate
。确切地说,只有那些不是UIElements的项目才会包装在ContentPresenter中。因此,如果将按钮集合指定给ItemsSource属性,则它们不会被包装,而是直接添加到ItemsPanel。要将
MyUserControl
添加为
MyCustomPanel
的直接子级,唯一的方法是创建派生的ItemsControl并重写
GetContainerForItemOverride
IsItemItsOwnContainerOverride
方法。