WPF: уменьшение размера текста в ContentPresenter

#c# #.net #wpf #contentpresenter #texttrimming

#c# #.net #wpf #contentpresenter #обрезка текста

Вопрос:

Есть ли простой способ просто заставить обрезку текста работать с ContentPresenter?

У меня есть неявные стили для TextBlock и AccessText, для которых для обрезки текста установлено значение CharacterEllipsis, но оно не распознается ContentPresenter. Я могу изменить ContentPresenter на AccessText или TextBlock и установить его там, но тогда шаблон обрабатывает только текстовое содержимое.

Есть предложения?

Спасибо!

Ответ №1:

Неявные стили для элементов, которые являются производными от UIElement, но не элемента управления, не применяются, если элемент определен в шаблоне элемента управления, если неявный стиль не определен в ресурсах приложения. То же самое справедливо для текстовых блоков, используемых ContentPresenter.

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

 <Window.Resources>
    <Style TargetType="TextBlock">
        <Setter Property="Foreground" Value="Red" />
    </Style>
</Window.Resources>
<StackPanel>
    <Button Content="Will not be red" />
    <TextBlock Text="Will be red" />
</StackPanel>
  

Если вы возьмете точно такой же стиль и перенесете его в Ресурсы приложения, то оба будут красными:

 <Application.Resources>
    <Style TargetType="TextBlock">
        <Setter Property="Foreground" Value="Red" />
    </Style>
</Application.Resources>
  

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

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

Комментарии:

1. @H.B. — Я покрасил город в красный цвет!

2. Спасибо за это объяснение! Другое решение, опубликованное в другом месте, определяет стиль в ContentPresenter. Ресурсы внутри ControlTemplate. Я попробовал этот подход, и он работает. В нашем случае перенос неявного стиля в приложение. Ресурсы будут работать так, как предполагается обрезать все текстовые блоки. Аналогично ли добавление неявной datatemplate тому, что я сделал выше? Как определить datatemplate, чтобы можно было поддерживать произвольный контент?

3. @dex3703 — У вас не может быть «глобальной» неявной таблички данных. Вам пришлось бы настроить таргетинг на конкретные типы, которые вы отображаете, т. Е. String или любые пользовательские классы, которые у вас могут быть. Неявный DataTemple был бы полезен в случаях, когда вы не хотите переопределять ControlTemplate (просто для добавления обрезки текста). Но опять же, неявный DataTemplate не будет применяться к произвольному контенту.

4. Есть ли какая-то причина, по которой добавление обрезки текста или обтекания текста так сложно?

5. @dex3703 — Ну, в общем, вы бы не хотели применять обрезку / перенос текста ко всем текстовым блокам. Например, это на самом деле не имеет смысла в кнопках (в большинстве случаев). Вот почему неявные стили не применяются, если они не находятся в ресурсах приложения (или, по-видимому, в шаблоне). Но свойств слишком много, чтобы предоставлять их все родительским элементам. Но, возможно, чтобы ответить на ваш вопрос, но я не совсем уверен, почему 🙂

Ответ №2:

Благодаря этой идее Джеймса Ньюджента: «Стиль WPF, который помещает многоточие в содержимое кнопки без замены ContentPresenter текстовым блоком и, таким образом, теряет способность поддерживать ключи доступа».

У меня это сработало:

 <ContentPresenter.Resources>
    <Style TargetType="TextBlock">
        <Setter Property="TextTrimming" Value="CharacterEllipsis"></Setter>    
    </Style>
</ContentPresenter.Resources>
  

Комментарии:

1. Это очень разумное решение. Это работает очень хорошо. Спасибо, что поделились!

2. Переопределение стилей — мой предпочтительный способ обработки такого рода вещей!