Создать элемент управления Silverlight, который можно использовать в качестве корня макета - PullRequest
2 голосов
/ 21 сентября 2011

Как создать в Silverlight элемент управления, который можно использовать в качестве корня макета, но при этом иметь свойство «Шаблон», чтобы я мог обернуть содержимое пользователя в другой элемент управления, используя стиль?

Моя текущая реализация близка, она берет контент, который пользователь помещает в элемент управления, и оборачивает его, но пользователь должен поместить сетку или панель, если есть несколько элементов управления для контента.

- Обновление -
Это код, который я использую, который не будет работать в качестве rootlayout для нескольких детей, если пользователь не поместит сетку вокруг своего контента. Если я наследую от Grid или Panel, я получаю ошибку о недоступности свойства DefaultStyleKey.

public class BusyControl :ContentControl
{
    public BusyControl()
    {
        this.DefaultStyleKey = typeof(BusyControl);
    }
}

<Style TargetType="local:BusyControl">
    <Setter Property="Template">
        <Setter.Value>                
            <ControlTemplate TargetType="local:BusyControl">
                <telerik:RadBusyIndicator DisplayAfter="0:0:0.5" IsBusy="{Binding IsBusy}" BusyContent="{Binding BusyMessage}">
                    <ContentPresenter Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}"/>
                </telerik:RadBusyIndicator>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Вот как я хочу, чтобы пользователь мог использовать мой новый элемент управления без необходимости оборачивать его содержимое в панель или сетку.

<cdc:BusyControl x:Name="BusyControl">
        <some:Control x:Name="Control1" />
        <some:Control x:Name="Control2" />
    </cdc:BusyControl>

Ответы [ 3 ]

1 голос
/ 22 сентября 2011

Мне кажется, что вы хотите получить контроль от ItemsControl, а не ContentControl. В любом ControlTemplate, который вы используете, вы можете поместить элементы управления, используя ItemsPresenter вместо ContentPresenter, который вы использовали бы в ContentControl.

0 голосов
/ 21 сентября 2011

Вы можете наследовать свой элемент управления от Panel, если хотите, чтобы он мог иметь несколько детей.Вам придется справиться с раскладкой дочерних элементов управления панели, если вы сделаете это.См. Эту статью MSDN о создании пользовательских панелей .

Затем вы можете указать свой шаблон и вставить пользовательский контент в шаблон.

0 голосов
/ 21 сентября 2011

Я думаю, что если вы хотите использовать несколько элементов управления, то есть дочерних элементов, в качестве содержимого, вам нужно использовать панель какого-либо типа, которая является базовым классом для свойства .Children.

Не уверен, применимо ли этов вашей ситуации.Мне было трудно понять, что именно происходит в вашем вопросе.Может быть, вы можете сделать пользовательский элемент управления, который наследуется от ContentControl.Как вы можете знать или не знать, для пользовательских элементов управления нужен ключ стиля по умолчанию.С помощью пользовательского элемента управления вам нужно определить шаблон в стиле по умолчанию.Теперь шаблон может иметь ContentControl где-то внутри него, и его свойство содержимого должно быть привязкой шаблона к свойству contentcontrol.content.Или вы можете переопределить функцию OnContentChanged и делать что угодно в этой функции переопределения (например, поместить отдельный объект в элемент управления самостоятельно ... или для нескольких объектов создайте новую сетку / панель, а затем установите объекты как сетку / панелиchildren для пользователя и затем делайте то, что вы делаете с сеткой / панелью. Вам нужно было бы установить / связать свойство content в вашем новом элементе управления. Имеет смысл?

Я не знаю о вашей ошибке с ключом стиля по умолчанию, и у меня нет каких-либо элементов управления telerik, но вы не можете просто унаследовать от своего индикатора активности telerik?правильный путь).

protected override void OnContentChanged( object oldContent, object newContent )
    {
        //I dont know how you are assigning content, 
        //but i would say if it's IEnumerable and count is > 1 it should use your panel
        var newMultiContent = newContent as System.Collections.IEnumerable;
        if ( newMultiContent!=null && newMultiContent.Cast<object>().Count()>1)
        {
            var myNewContentContainer = new StackPanel();//or grid or whatever
            myNewContentContainer.Children.Clear();
            //add children
            foreach (var item in newMultiContent.OfType<UIElement>())
                myNewContentContainer.Children.Add(item);
            //instead of the old content that wasn't what you wanted, use the new content container
            base.OnContentChanged( oldContent, myNewContentContainer );
            //or maybe try this and call the base method at the beginning...
            Content = myNewContentContaint
        }
        else
            base.OnContentChanged( oldContent, newContent );
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...