Как сохранить и отформатировать контент в wpf UserControl, не прерывая перенос текста? - PullRequest
2 голосов
/ 19 мая 2009

У меня есть этот блок xaml, который позволяет красиво обернуть текст гиперссылки:

<TextBlock>
  <Hyperlink TextDecorations="None" Click="DoSomething">
    <TextBlock TextWrapping="Wrap">
Click this text that is really rather long and overly descriptive in order to do something.
    </TextBlock>
  </Hyperlink>
</TextBlock>

В конечном итоге это выглядит так:

alt text

Я хочу создать элемент управления, чтобы упростить этот xaml примерно с таким синтаксисом:

<MyLinkControl Click="DoSomething">
Click this text that is really rather long and overly descriptive in order to do something.
</MyLinkControl>

Ну, я попробовал несколько вещей, чтобы заставить это работать как UserControl, но независимо от того, что я получаю в итоге:

alt text

Может кто-нибудь предложить правильный способ создания такого элемента управления?

1 Ответ

2 голосов
/ 19 мая 2009

Я не могу определить, почему UserControl неправильно форматирует текст, хотя это должно быть возможно. Однако, чтобы решить начальную проблему, я бы использовал для этого CustomControl вместо UserControl.

Первое, что мы сделаем, это создадим CustomControl. К сожалению, ни TextBlock, ни Hyperlink не являются производными от Control, поэтому, хотя было бы неплохо просто расширить один из них, мы не можем.

[ContentProperty("Text")]
[TemplatePart(Name = "PART_HyperlinkContainer", Type=typeof(Hyperlink))]
[TemplatePart(Name = "Part_TextContainer", Type = typeof(TextBlock))]
public class CustomLinker : Control
{
    static CustomLinker()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomLinker), new FrameworkPropertyMetadata(typeof(CustomLinker)));
    }

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(CustomLinker), new UIPropertyMetadata(""));  

    public ICommand Click
    {
        get { return (ICommand)GetValue(ClickProperty); }
        set { SetValue(ClickProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Click.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ClickProperty =
        DependencyProperty.Register("Click", typeof(ICommand), typeof(CustomLinker), new UIPropertyMetadata(null));
}

Все, что нужно элементу управления, - это событие Click и свойства Text. Для события click я решил вместо этого использовать команду. Гиперссылка поддерживает команды, и это облегчает использование в долгосрочной перспективе.

ContentProperty сообщает CustomControl, что делать с содержимым, установленным непосредственно внутри него. Две TemplateParts определяют TextBlock, который будет содержать наш текст, и Гиперссылку, которая содержит этот текстовый блок.

Теперь, наряду с пользовательским элементом управления, был создан шаблон по умолчанию, так что давайте посмотрим на это. И создайте TemplateParts, который мы определили.

<Style TargetType="{x:Type local:CustomLinker}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomLinker}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <TextBlock>
                      <Hyperlink x:Name="PART_HyperlinkContainer"
                                 TextDecorations="None"
                                 Command="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Click}">
                        <TextBlock x:Name="Part_TextContainer"
                                   TextWrapping="Wrap"
                                   Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text}" />
                      </Hyperlink>
                    </TextBlock>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

И это все, что нужно. Теперь мы можем использовать наш элемент управления,

<local:CustomLinker Click="{Binding MyCommand}">
    Click this text that is really rather long and overly descriptive in order to do something.
</local:CustomLinker>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...