ContentPresenter 而不是 UserControl 添加到我的自定义面板
ContentPresenter instead of UserControl is added to my custom panel
我创建了一个继承自 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 的方式上。但是不知道怎么修复。
在 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>
The problem is that for some reason InternalChildren consist of ContentPresenter items instead of my user controls.
这是因为 ItemsControl
将所有项目包装在 ContentPresenter
中,除非它们是 UIElements
。如果您绑定到 UIElements
的集合,例如 Buttons
,则不会创建 ContentPresenter
,但也不会应用 ItemTemplate
。
您可以按照@Clemens 的建议设置 ContentPresenter
容器的 MinWidth
,或者您可以通过实现自己的自定义 [=11] 来阻止创建 ContentPresenters
=] 并覆盖 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);
}
}
我创建了一个继承自 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 的方式上。但是不知道怎么修复。
在 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>
The problem is that for some reason InternalChildren consist of ContentPresenter items instead of my user controls.
这是因为 ItemsControl
将所有项目包装在 ContentPresenter
中,除非它们是 UIElements
。如果您绑定到 UIElements
的集合,例如 Buttons
,则不会创建 ContentPresenter
,但也不会应用 ItemTemplate
。
您可以按照@Clemens 的建议设置 ContentPresenter
容器的 MinWidth
,或者您可以通过实现自己的自定义 [=11] 来阻止创建 ContentPresenters
=] 并覆盖 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);
}
}