Пользовательский контроль WPF и прямая поддержка контента - PullRequest
1 голос
/ 08 января 2011

Я довольно новичок в WPF и немного застрял, поэтому любая помощь будет признательна.

Я пытаюсь написать пользовательский элемент управления WPF, который включает в себя несколько элементов функциональности, которые у меня уже есть (например, сортировка, фильтрация, стандартные меню и т. Д.), Но в хорошем аккуратном пакете, чтобы избежать повторения.

В любом случае я создал пользовательский элемент управления (на основе элемента управления), а затем в Generic.Xaml

следующее
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Controls.ListViewExtended">
    <Style TargetType="{x:Type local:ListViewExtended}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ListViewExtended}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <ListView>
                            <ListView.View>
                                <GridView>
                                <!-- Content goes here -->                             
                                </GridView> 
                            </ListView.View>
                        </ListView>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Когда я пытаюсь добавить GridViewColumns (или любой другой элемент управления), как показано ниже ...

<elv:ListViewExtended>
   <GridView>
        <GridViewColumn Width="140" Header="Column 1" />
        <GridViewColumn Width="140" Header="Column 2" />
        <GridViewColumn Width="140" Header="Column 3" />
   </GridView>
</elv:ListViewExtended>

Я получаю "... не поддерживает прямой контент" ошибка.

Я создал свойство зависимости (снова ниже), которое позволяет добавлять GridView, но оно по-прежнему не работает.

public static DependencyProperty GridViewProperty;

public static string GridViewHeader(DependencyObject target) 
{
    return (string)target.GetValue(GridViewProperty); 
}
public static void GridViewHeader(DependencyObject target, string value) 
{
    target.SetValue(GridViewProperty, value); 
} 

Заранее спасибо

Ответы [ 3 ]

18 голосов
/ 22 мая 2014

Все, что вам нужно, это указать ContentPropertyAttribute.

[ContentProperty("MainContent")]
public class GroupPanel : Control
{
    public GroupPanel()
    {
        DefaultStyleKey = typeof(GroupPanel);
    }

    public object MainContent
    {
        get { return GetValue(MainContentProperty); }
        set { SetValue(MainContentProperty, value); }
    }

    public static readonly DependencyProperty MainContentProperty =
        DependencyProperty.Register("MainContent", typeof(object), typeof(GroupPanel), null);
}

Ссылка: http://msdn.microsoft.com/en-us/library/system.windows.markup.contentpropertyattribute(v=vs.90).aspx

3 голосов
/ 03 декабря 2013

Я использую это простое решение в наших проектах для поддержки прямого содержимого в пользовательских элементах управления:

Добавьте «CustomControl» в ваш проект и извлеките этот элемент управления из класса «UserControl» вместо «Control»:

public class MyCustomControl: UserControl
{
    static MyCustomControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), 
            new FrameworkPropertyMetadata(typeof(MyCustomControl)));
    }
}

Когда вы добавляете CustomControl в свой проект, Visual Studio (я использую 2012) автоматически добавляет папку «Темы», включая файл с именем «Generic.xaml».Этот файл содержит ResourceDictionary для определения стиля (шаблона) вашего CustomControl.

Вы найдете базовый шаблон для вашего CustomControl, который уже используется как DefaultStyle.Для прямой поддержки содержимого поместите ContentPresenter где-нибудь внутри этого шаблона с привязкой родительского содержимого:

<Style TargetType="{x:Type local:MyCustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyCustomControl}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Теперь возможно добавить содержимое в свой CustomControl:

<Window x:Class="MyApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:MyApplication"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <controls:MyCustomControl>
                <TextBlock>Hello</TextBlock>
        </controls:MyCustomControl>
    </Grid>
</Window>

Надеюсь, это поможет!

2 голосов
/ 08 января 2011

Унаследуйте свой пользовательский элемент управления от ListView, а не от Control. Это определенно заставит вас изменить шаблон, но я рекомендую вам прочитать больше документации о том, как это сделать (например, статья Саши Барбера: Создание и использование собственного элемента управления WPF ).

Удачи в обучении!

...