Question

The TextWrapping property of the TextBox has three possible values:

  • Wrap
  • NoWrap
  • WrapWithOverflow

I would like to bind to the IsChecked property of a MenuItem. If the MenuItem is checked, I want to set the TextWrapping property of a TextBox to Wrap. If the MenuItem is not checked, I want to set the TextWrapping property of the TextBox to NoWrap.

To sum up, I am trying to bind a control that has two states to two values of an enumeration that has more than two values.

[edit] I would like to accomplish this in XAML, if possible.

[edit] I figured out how to do this using an IValueConverter. Perhaps there is a better way to do this? Here is what I did:


In Window.Resources, I declared a reference to my ValueConverter.

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

In my TextBox, I created the binding to a MenuItem and included the Converter in the binding statement.

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

and the ValueConverter looks like this:

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();
        }
    }
Was it helpful?

Solution

If you want to do this all in xaml you need to use a Style and a 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>

OTHER TIPS

I think that the only and right the typical way to do this is to use a value converter like you already have done.

Sometimes you can find an existing value converter that you have built already ... or even better that Microsoft has built for you. For example, in System.Windows.Controls, Microsoft has written a BooleanToVisibilityConverter ... which converts a bool into a Visibility enum ... converting True to Visible and False to Collapsed (and not worrying about Hidden).

One idea is to use .NET Reflector, navigate to the System.Windows.Data.IValueConverter, and then use the Analyze feature (in particular, 'Used by') and see what things have implemented IValueConverter ... and you just might get lucky to find a converter that suits your purpose.

On a related note, BooleanToVisibilityConverter is very similar to what you are trying to do above.

Edit: I really like Todd White's suggestion of styling the TextBox and using a DataTrigger in the Style. It is a very good idea if you want to avoid a Converter.

I assume you are talking about .NET. I don't think databinding will work here because the values are not of the same type (boolean vs enum). The easiest solution would be to handle the CheckedChanged event of that menu item and adjust the wrap mode of the textbox accordingly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top