ContentPresenter而不是UserControl已添加到我的自定义面板

时间:2019-05-22 14:33:46

标签: c# wpf custom-controls itemscontrol

我创建了一个继承自Canvas的自定义面板。我想用它来查看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>

如您所见,我的用户控件的MinWidth设置为200。

现在,在我的自定义面板中,重写了ArrangeOverride方法:

    protected override Size ArrangeOverride(Size arrangeSize)
    {
        foreach (UIElement obj in InternalChildren)
        {
           //some other code   
        }
        return arrangeSize;
    }

问题是由于某种原因,InternalChildren包含ContentPresenter项而不是我的用户控件。当然,在每个ContentPresenter中都有我的用户控件,但这不是我想要的。我需要在这里阅读userControl的MinWidth,但我是从ContentPresenter(始终为0)中读取的。

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

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

其中Buttons只是Button控件的列表,一切都按预期工作。因此,我认为问题可能出在我如何使用ItemsControl上。但是不知道如何修复它。

2 个答案:

答案 0 :(得分:1)

在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>

答案 1 :(得分:1)

  

问题是由于某种原因,InternalChildren包含ContentPresenter项而不是我的用户控件。

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

您可以按照@Clemens的建议设置MinWidth容器中的ContentPresenter,也可以通过实现自己的自定义ContentPresenters来阻止创建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);
    }
}
相关问题