ContentPresenter вместо UserControl добавляется в мою пользовательскую панель - PullRequest
0 голосов
/ 22 мая 2019

Я создал пользовательскую панель, унаследованную от 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 есть мой пользовательский элемент управления, но это не то, чем я хотел бы быть. Мне нужно прочитать здесь MinWidth моего userControl, но вместо этого я читаю его из ContentPresenter (который всегда равен 0).

Когда я делаю очень простой тест:

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

где Buttons - это просто список элементов управления Button, все работает как положено. Поэтому я думаю, что проблема может быть где-то в том, как я использую ItemsControl. Но понятия не имею, как его починить.

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Проблема в том, что по какой-то причине InternalChildren состоят из элементов ContentPresenter вместо моих пользовательских элементов управления.

Это потому, что ItemsControl оборачивает все элементы в ContentPresenter, если они не UIElements.Если вы связываетесь с коллекцией UIElements, как, например, Buttons, не создается ContentPresenter, но также не применяется ItemTemplate.

Вы можете установить MinWidth изконтейнеры ContentPresenter, предложенные @Clemens, или вы можете предотвратить создание 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);
    }
}
1 голос
/ 22 мая 2019

Установите свойство MinWidth ContentPresenter в ItemContainerStyle:

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