如何在Border Style中编写WPF DataTrigger以及如何在Setter中查找元素?

时间:2015-12-18 06:51:25

标签: wpf triggers datatrigger

我需要一个WPF DataTrigger来实现Border的Mouse Hover功能。边框包含一个按钮,最初它的可见性是折叠的。按钮应仅在鼠标悬停时可见,否则折叠。

<Border Width="100" Height="30" HorizontalAlignment="Center" VerticalAlignment="Top" Background="#FFF2FFC6" Margin="0,20,0,0">
    <Button x:Name="btn" Content="iApp" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75" Visibility="Collapsed" />
    <Border.Style>
        <Style TargetType="Border">
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True">
                    <Setter TargetName="btn" Property="Visibility" Value="Visible"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
</Border>
  

注意:我只需要DataTrigger。不要建议事件触发器。

在这里,我无法找到TargetName,它会产生构建错误&#34; 错误1名称&#34; btn&#34;无法识别&#34;

2 个答案:

答案 0 :(得分:1)

  1. TragetName不能在Style.Triggers中使用。它应该在ControlTemplete.Triggers中使用。
  2. 您可以编写这样的代码(不测试)。
  3. 在xaml中添加命名空间

         xmlns:converter="clr-namespace:yours coverter's namespace"
    

    在您的资源中添加转换器

         <UserControl.Resources>
               <converter:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
         </UserControl.Resources>
    

    这是你的边界:

         <Border x:Name="m_Border" Margin="0,20,0,0">
         <Button x:Name="btn" Content="iApp"  Visibility="{Binding  IsMouseOver,ElementName=m_Border,Converter="{StaticResource BooleanToVisibilityConverter},ConverterParameter=Normal}"}" />
        </Border> 
    
    1. 使用此转换器

        public enum BooleanToVisibilityConverterType
        {
              /// <summary>
              /// Normal
              /// </summary>
              Normal = 1,
      
              /// <summary>
              /// Reverse
              /// </summary>
              Reverse = 2
         }
      
        public class BooleanToVisibilityConverter : IValueConverter
        {
              public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
              {
                   var targertValue = false;
      
               if (value == null)
               {
                   throw new Exception("BooleanToVisibilityConverter - Convert Error");
               }
               else if (!Boolean.TryParse(value.ToString(), out targertValue))
               {
                   throw new Exception("BooleanToVisibilityConverter - Convert Error");
               }
               else
               {
                   var parameterValue = BooleanToVisibilityConverterType.Normal;
      
                   if (parameter != null)
                   {
                       Enum.TryParse<BooleanToVisibilityConverterType>(parameter.ToString(), out parameterValue);
                   }
      
                   if (parameterValue == BooleanToVisibilityConverterType.Reverse)
                   {
                  return targertValue ? Visibility.Collapsed : Visibility.Visible;
                   }
                   else
                   {
                       return targertValue ? Visibility.Visible : Visibility.Collapsed;                    
                   }
               }
           }
      
      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      {
          var targetValue = Visibility.Collapsed;
      
          if (value == null)
          {
              throw new Exception("BooleanToVisibilityConverter - ConvertBack Error");
          }
          else if (!Enum.TryParse<Visibility>(value.ToString(), out targetValue))
          {
              throw new Exception("BooleanToVisibilityConverter - ConvertBack Error");
          }
          else
          {
              var parameterValue = BooleanToVisibilityConverterType.Normal;
      
              if (parameter != null)
              {
                  Enum.TryParse<BooleanToVisibilityConverterType>(parameter.ToString(), out parameterValue);
              }
      
              if (parameterValue == BooleanToVisibilityConverterType.Reverse)
              {
                  return targetValue == Visibility.Visible ? false : true;
              }
              else
              {
                  return targetValue == Visibility.Visible ? true : false;
              }
          }
      }
      

答案 1 :(得分:1)

TargetName主要用于控件模板中,而不仅仅是在样式中。

来自MSDN

  

您可以将此属性设置为范围内任何元素的名称   setter集合的位置(此setter的集合   应用的一部分。这通常是一个在其中的命名元素   包含此setter的模板。

另外,为了满足您的需求,您应该将触发器设置为Button而不是Border

   <Border x:Name="border" Width="100" Height="30" HorizontalAlignment="Center" VerticalAlignment="Top" Background="#FFF2FFC6" Margin="0,20,0,0">
        <Button x:Name="btn" Content="iApp" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75" >
            <Button.Style>
                <Style>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=border, Path=IsMouseOver}" Value="false">
                            <Setter Property="Button.Visibility" Value="Collapsed"></Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </Border>