Как связать свойство TextWrapping элемента TextBox со значением IsChecked элемента MenuItem? - PullRequest
5 голосов
/ 30 октября 2008

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

  • Wrap
  • Nowrap
  • WrapWithOverflow

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

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

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

[править] Я понял, как это сделать, используя IValueConverter. Возможно, есть лучший способ сделать это? Вот что я сделал:


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

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

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

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();
        }
    }

Ответы [ 3 ]

9 голосов
/ 31 октября 2008

Если вы хотите сделать все это в xaml, вам нужно использовать Style и 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>
0 голосов
/ 30 октября 2008

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

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

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

В связанной заметке BooleanToVisibilityConverter очень похож на то, что вы пытаетесь сделать выше.

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

0 голосов
/ 30 октября 2008

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

...