在usercontrol中使用trigger magic

时间:2013-12-24 11:32:40

标签: c# wpf triggers

我正在构建一个可重用的控件,用于编辑特定的类类型。假设它看起来如下:

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

编辑对象将由依赖项属性提供,并设置为整个控件的DataContext。 (也可以通过DataContext提供,第二个想法)。

我希望在没有提供数据的情况下禁用TextBox。有没有办法创建某种触发器,当没有可用数据时,它会自动切换Enabled属性? (=某些Data依赖项属性为null或DataContext为null)或者我应该从代码隐藏中执行所有逻辑吗?

2 个答案:

答案 0 :(得分:4)

你可以通过Trigger来做到这一点。只需将DataContext与x:Null进行比较,然后通过Setter将IsEnabled设置为false。

 <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 (如果要检查UserControl的DataContext)

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

注意 -

  

UserControl的DataContext由其子进程自动继承   TextBox将继承它,除非您明确设置它。但是,除非您使用 FrameworkPropertyMetadataOptions.Inherits 注册,否则您的自定义DP不适用。

答案 1 :(得分:1)

由于已经给出了关于触发器的答案,我想提供一种使用转换器作为替代方案的解决方案。 此转换器会考虑绑定到BooleanVisibility属性的可能性:

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

用法:

// 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>