Как связать свойство TextWrapping TextBox со значением IsChecked MenuItem?

Свойство TextWrapping TextBox имеет три возможных значения:

  • Сворачивать
  • Нет
  • WrapWithOverflow

Я хотел бы привязаться к свойству IsChecked объекта MenuItem. Если установлен флажок MenuItem, я хочу установить для свойства TextWrapping TextBox значение Wrap. Если MenuItem не отмечен, я хочу установить для свойства TextWrapping TextBox значение NoWrap.

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

[edit] Я хотел бы сделать это в XAML, если возможно.

[edit] Я понял, как это сделать, с помощью IValueConverter. Может, есть способ лучше? Вот что я сделал:


В Window.Resources я объявил ссылку на свой ValueConverter.

<local:Boolean2TextWrapping x:Key="Boolean2TextWrapping" />

В моем TextBox я создал привязку к MenuItem и включил Converter в оператор привязки.

TextWrapping="{Binding ElementName=MenuItemWordWrap, Path=IsChecked, Converter={StaticResource Boolean2TextWrapping}}"

и ValueConverter выглядит так:

public class Boolean2TextWrapping : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo cultureInfo)
        {
            if (((bool)value) == false)
            {
                return TextWrapping.NoWrap;
            }
            return TextWrapping.Wrap;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

person Timothy Lee Russell    schedule 30.10.2008    source источник
comment
Я пытаюсь сделать то же самое в SL 4, но мой конвертер никогда не вызывается. Xaml идентичен вашему ...   -  person Number8    schedule 18.03.2011


Ответы (3)


Если вы хотите сделать все это в xaml, вам необходимо использовать стиль и DataTrigger.

<StackPanel>
    <CheckBox x:Name="WordWrap">Word Wrap</CheckBox>
    <TextBlock Width="50">
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin lacinia nibh non augue. Pellentesque pretium neque et neque auctor adipiscing.

        <TextBlock.Style>
            <Style TargetType="{x:Type TextBlock}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsChecked, ElementName=WordWrap}" Value="True">
                        <Setter Property="TextWrapping" Value="Wrap" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</StackPanel>
person Todd White    schedule 31.10.2008
comment
Как TextBox узнает, что нужно переключиться на NoWrap, если IsChecked имеет значение False? Это работает, но я не понимаю почему. Это потому, что TextWrapping в TextBox имеет значение по умолчанию или что-то еще? - person Timothy Lee Russell; 31.10.2008
comment
Да, когда триггер больше не используется, он возвращается к значению по умолчанию. - person Todd White; 31.10.2008
comment
Как определить значение по умолчанию для данного свойства объекта, помимо экспериментов в отладчике? Другими словами, как я могу знать, что не следует делать DataTrigger, IsChecked = false и Setter, TextWrapping = NoWrap, предполагая, что он вернется к Wrap? Спасибо! - person Timothy Lee Russell; 01.11.2008
comment
Здесь на помощь приходит документация MSDN. В случае TextBlock.TextWrapping я нашел его здесь msdn.microsoft.com/en-us/library/. На этой странице написано: «По умолчанию используется TextWrapping.NoWrap». - person Todd White; 01.11.2008
comment
Мне это нравится. Я всегда стараюсь по возможности избегать использования конвертера. Я никогда раньше не использовал DataTrigger таким образом. Полезный трюк. - person cplotts; 02.11.2008

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

Иногда вы можете найти существующий преобразователь значений, который вы уже построили ... или даже лучше, который Microsoft построила для вас. Например, в System.Windows.Controls Microsoft написала BooleanToVisibilityConverter ... который преобразует bool в перечисление Visibility ... преобразовывая True в Visible и False в Collapsed (и не беспокоясь о Hidden).

Одна из идей - использовать .NET Reflector, перейти к System.Windows.Data.IValueConverter, а затем использовать функцию анализа (в частности, «Используется») и посмотреть, что реализовано в IValueConverter ... и вы просто можете получить повезло найти конвертер, который подходит для ваших целей.

Кстати, BooleanToVisibilityConverter очень похож на то, что вы пытаетесь сделать выше.

Изменить: мне очень нравится предложение Тодда Уайта стилизовать TextBox и использовать DataTrigger в Style. Это очень хорошая идея, если вы не хотите использовать конвертер.

person cplotts    schedule 30.10.2008

Я предполагаю, что вы говорите о .NET. Я не думаю, что здесь сработает привязка данных, потому что значения не одного типа (логическое или перечисление). Самым простым решением было бы обработать событие CheckedChanged этого пункта меню и соответствующим образом настроить режим переноса текстового поля.

person DCNYAM    schedule 30.10.2008