Передача TextBlock или коллекции строк в дочерний UserControl в WPF - PullRequest
1 голос
/ 24 февраля 2012

Я создал UserControl под названием InfoBox, который действует как причудливый текстовый блок (дополнительные кнопки и т. Д.).Работает нормально.Я могу использовать его в Blend следующим образом:

<myNS:InfoBox Text="Some Text"/>

, где 'Text' является свойством зависимости:

 public static readonly DependencyProperty TextProperty =
     DependencyProperty.Register("Text", typeof(string), typeof(InfoBox),
     new UIPropertyMetadata(null,ValueChanged));

и обрабатывается так:

    private static void ValueChanged(DependencyObject dpo,
                                     DependencyPropertyChangedEventArgs args)
    {
        ((InfoBox)dpo).TextBlock.Text = (string)args.NewValue;
    }

Когда я добавляю элемент управления в Blend, он отображается с образцом текста во время разработки, пока я не укажу Text = "Something", и в этом случае в конструкторе волшебным образом появится "Something".Отлично!

Но теперь я хочу передать больше, чем текст, я хочу иметь возможность использовать все функциональные возможности, которые вы встраиваете в текстовый блок.Выполнить, курсив и т. Д. *

Почему следующее не работает?

<myNS:InfoBox>
        <myNS:InfoBox.ReferenceBlock>
             <TextBlock>
                <Run Language="en-gb" Text="SampleSample"/><LineBreak/>
                <Run Language="en-gb"/><LineBreak/>
                <Run Language="en-gb" Text="MoreMoreMore"/>
             </TextBlock>   
        <myNS:InfoBox.ReferenceBlock>           
</myNS:InfoBox>

.

     public static readonly DependencyProperty ReferenceBlockProperty =
        DependencyProperty.Register("ReferenceBlock", typeof(TextBlock), 
        typeof(InfoBox), new UIPropertyMetadata(null, ReferenceBlockReceived));

[...]


     private static void ReferenceBlockReceived(DependencyObject dpo,
            DependencyPropertyChangedEventArgs args)
    {
        var textblock = (TextBlock)args.NewValue;
        if (textblock != null)
        {
            ((InfoBox)dpo).TextBlock.Inlines.Clear();
            ((InfoBox)dpo).TextBlock.Inlines.AddRange(textblock.Inlines);
        }
    }

TextBlock, полученный обработчиком, полностью пуст длянекоторая причина.Я ценю любую помощь.Этот материал WPF сложен!

Ответы [ 2 ]

0 голосов
/ 25 февраля 2012

В дополнение к ответу Фила я бы предложил изменить тип вашего свойства зависимости ReferenceBlock на object, а затем в вашем пользовательском элементе управления использовать ContentControl со свойством Content, связанным с ReferenceBlock - это будетпозволяет передавать произвольный контент, включая несколько строк текста:

<ControlTemplate TargetType="myNS:InfoBox">
    <ContentControl Content="{TemplateBinding ReferenceBlock}" />
</ControlTemplate>

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

0 голосов
/ 25 февраля 2012

К сожалению, не все так просто.TextBlock поддерживает элементы типа Выполните через свойство зависимости, называемое Inlines , а также пару интерфейсов.Было бы возможно, но трудно воспроизвести это поведение в вашем необычном текстовом поле.

Я рекомендую вам скачать бесплатный декомпилятор Jetbrain DotPeek , который позволит вам изучить реализацию TextBlock, чтобы понять, что требуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...