2012-03-08 154 views
0

我试图让一个由几个按钮和一对夫妇的标签,自定义控制,但按键都应该是不可见的,只显示在其中的内容。通过将它们设置为透明,我可以摆脱边框,背景等。但是,每当我将鼠标悬停在默认窗口悬停效果上时,再次显示整个按钮。我已经尝试过很多关于自定义控件的指南,但最终无法弄清楚如何覆盖它。基本上我的问题归结为,其中有多少可以被放置在generic.xaml文件,什么组织我有该文件中使用,以及是否有任何其他地方,这些造型应该走呢?我意识到这是一个非常基本的问题,但这只是让我无法弄清楚具体的答案。谢谢!自定义控件样式/触发器

电流XAML:

<Style TargetType="{x:Type local:TimePicker}"> 
    <Setter Property="Background" Value="Transparent" /> 
    <Setter Property="BorderBrush" Value="Transparent" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:TimePicker}"> 
       <Border Background="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="{TemplateBinding BorderThickness}" 
         Height="{TemplateBinding Height}" 
         Width="{TemplateBinding Width}"> 
        <StackPanel Orientation="Horizontal"> 
         <StackPanel x:Name="PART_Root" 
            Orientation="Horizontal" 
            HorizontalAlignment="Center"> 
          <ToggleButton x:Name="PART_HourButton" 
              HorizontalAlignment="Center" 
              VerticalAlignment="Center" 
              Margin="0" 
              Background="Transparent" 
              BorderBrush="Transparent" 
              BorderThickness="0" 
              Height="{Binding ElementName=PART_IncDecPanel, Path=ActualHeight}" 
              Width="{Binding ElementName=PART_HourButton, Path=ActualHeight}" 
              Content="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Hour}"> 
                    <ToggleButton.Triggers> 
            <Trigger Property="IsMouseOver" Value="True"> 
             <Setter Property="Background" Value="Transparent" /> 
            </Trigger> 
           </ToggleButton.Triggers> 
          </ToggleButton> 
          <Label x:Name="PART_HourMinSeparator" 
            HorizontalAlignment="Center" 
            VerticalAlignment="Center" 
            Margin="0" 
            Content=":" /> 
          <ToggleButton x:Name="PART_MinButton" 
              HorizontalAlignment="Center" 
              VerticalAlignment="Center" 
              Margin="0" 
              Background="Transparent" 
              BorderBrush="Transparent" 
              BorderThickness="0" 
              Height="{Binding ElementName=PART_HourButton, Path=ActualHeight}" 
              Width="{Binding ElementName=PART_HourButton, Path=ActualWidth}" 
              Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Minute}" /> 
          <StackPanel x:Name="PART_IncDecPanel" HorizontalAlignment="Center" VerticalAlignment="Center"> 
           <Button x:Name="PART_IncreaseTime" 
             Background="Transparent" 
             BorderBrush="Transparent" 
             BorderThickness="0" 
             HorizontalAlignment="Center" 
             HorizontalContentAlignment="Center" 
             VerticalAlignment="Center" 
             VerticalContentAlignment="Center" 
             Margin="0" 
             Padding="0" 
             Width="22" 
             Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IncreaseImage.ActualHeight}"> 
            <Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IncreaseImage}" /> 
           </Button> 
           <Button x:Name="PART_DecreaseTime" 
             Background="Transparent" 
             BorderBrush="Transparent" 
             BorderThickness="0" 
             HorizontalContentAlignment="Center" 
             HorizontalAlignment="Center" 
             VerticalAlignment="Center" 
             VerticalContentAlignment="Center" 
             Margin="0" 
             Padding="0" 
             Height="{Binding ElementName=PART_IncreaseTime, Path=ActualHeight}" 
             Width="{Binding ElementName=PART_IncreaseTime, Path=ActualWidth}"> 
            <Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DecreaseImage}" /> 
           </Button> 
          </StackPanel> 
         </StackPanel> 
        </StackPanel> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
+2

如果你想按钮,看上去并不像按钮,当你将鼠标放在它们上面时,不会像按钮一样反应,那么你确定你真的想要按钮吗?但对于你的问题,你将需要替换几乎整个按钮的默认模板。 – 2012-03-08 17:58:26

+0

我是否在generic.xaml中执行此操作?我会在ToggleButton轮廓或其他地方做到这一点吗? – 2012-03-08 18:28:14

+1

非常符合您的用户控制。为你的ToggleButton设置一个样式。用这种方式使用setter来设置模板。在模板中只需包含ContentPresenter(如flq建议),然后最终得到一个没有自己展示的按钮。请记住,如果您决定要保留模板的某些部分,但不是全部(可能在检查时改变外观),则必须在自己的模板中重新实现该模板。 – 2012-03-08 18:39:28

回答

1

WPF使用“无外观的控制,”这基本上意味着你可以改变整个视觉部分(在设计 - 或运行时)的控制,而无需改变其代码或该代码的行为。您已经在使用此概念为您的TimePicker控件创建默认样式。如果要从该样式中删除ControlTemplate,则在运行时不会看到任何内容,因为控件本身只是C#或VB代码中定义的行为。

因为它听起来就像你要保持你的按钮的行为,而是完全改变它的外表,这是重新模板的理想方案。这里是一个非常简单的例子,将只显示内容(在ContentPresenter):

<Button Content="Hello Template"> 
    <Button.Template> 
     <ControlTemplate TargetType="{x:Type Button}"> 
      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
           VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
     </ControlTemplate> 
    </Button.Template> 
</Button> 

你可能会想一些更添加到模板,就像一个透明边框捕捉鼠标输入,也许一些触发器。你试图使用一个触发切换按钮在您的示例的方式不正确(FrameworkElement的Triggers集合只适用于EventTriggers),但一个控件模板或样式里面,这个模式会奏效。

如果你想在同一样式应用到您的TimePicker控件模板内的每个按钮可以添加一个默认的按钮样式到您的ControlTemplate资源集合:

<ControlTemplate TargetType="{x:Type MyControl}"> 
    <ControlTemplate.Resources> 
     <Style TargetType="{x:Type Button}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type Button}"> 
         <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </ControlTemplate.Resources> 
    ... 
</ControlTemplate> 
+0

好的,我的主要问题是不知道将触发器放置在层次结构中的哪个位置。感谢您解释得非常好的回复! – 2012-03-08 21:47:39