Spook
Spook

Reputation: 25927

Using trigger magic inside usercontrol

I'm building a reusable control meant for editing specific class type. Suppose, that it looks like the following:

<Grid>
    <StackPanel Orientation="Horizontal">
        <Label>Name</Label>
        <TextBox Text="{Binding Name, Mode=TwoWay}" />
    </StackPanel>
</Grid>

The edited object will be provided by a dependency property and set as DataContext of the whole control. (It may be provided through DataContext as well, on the second thought).

I want the TextBox to be disabled, when there is no data provided. Is there a way to create some kind of trigger, which will automagically switch Enabled property, when there's no data available? (= either some Data dependency property is null or the DataContext is null) Or should I do all the logic from the code-behind?

Upvotes: 0

Views: 78

Answers (2)

Silvermind
Silvermind

Reputation: 5944

Since the answer about triggers has already been given, I want to offer a solution using a converter as an alternative. This converter takes into account the possibility of binding to a either a Boolean or Visibility property:

public class IsNotNullConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
                          System.Globalization.CultureInfo culture)
    {
        bool result = (value != null);
        if (targetType == typeof(Visibility))
            return result ? Visibility.Visible : Visibility.Collapsed;
        return result;
    }

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

Usage:

// xaml namespace declaration
xmlns:Converters="clr-namespace:MyProject.Converters"

<Grid>
    <Grid.Resources>
        <Converters:IsNotNullConverter x:Key="IsNotNullConverter"/>
    </Grid.Resources>
    <StackPanel Orientation="Horizontal">
        <Label>Name</Label>
        <TextBox Text="{Binding Name, Mode=TwoWay}"
                 IsEnabled={Binding Name,
                            Converter={StaticResource IsNotNullConverter}}"
                 Visibility={Binding Name,
                             Converter={StaticResource IsNotNullConverter}}" />
    </StackPanel>
</Grid>

Upvotes: 1

Rohit Vats
Rohit Vats

Reputation: 81253

You can do that via Trigger. Simply compare DataContext with x:Null and set IsEnabled to false in that case via Setter.

 <TextBox Text="{Binding Name, Mode=TwoWay}">
     <TextBox.Style>
        <Style TargetType="TextBox">
           <Style.Triggers>
              <Trigger Property="DataContext" Value="{x:Null}">
                 <Setter Property="IsEnabled" Value="False"/>
              </Trigger>
           </Style.Triggers>
        </Style>
     </TextBox.Style>
  </TextBox>

UPDATE (In case want to check DataContext of UserControl)

<Style.Triggers>
   <DataTrigger Binding="{Binding DataContext,
                    RelativeSource={RelativeSource Mode=FindAncestor, 
                                AncestorType=UserControl}}"
                Value="{x:Null}">
        <Setter Property="IsEnabled" Value="False"/>
    </DataTrigger>
</Style.Triggers>

NOTE -

UserControl's DataContext is automatically inherited by its child so TextBox will inherit it unless you set it explicitly. However, not true for your custom DP unless you register with FrameworkPropertyMetadataOptions.Inherits.

Upvotes: 4

Related Questions