2012-02-10 34 views
20

Tôi có kiểu chuẩn cho các nút của mình nhưng tôi muốn một số phần nhất định của kiểu có thể định cấu hình được. ví dụ. Tôi có một đường viền xuất hiện khi MouseOver được kích hoạt cho nút và tôi muốn màu đường viền được cấu hình.Gắn kết mẫu với các thuộc tính đính kèm

Sau bài viết này: http://www.thomaslevesque.com/2011/10/01/wpf-creating-parameterized-styles-with-attached-properties/ Tôi nghĩ tôi có thể sử dụng các thuộc tính đính kèm và TemplateBinding để đạt được điều này.

tôi tạo ra các tài sản gắn liền sau:

public static class ThemeProperties 
{ 
    public static Brush GetButtonBorderColour(DependencyObject obj) 
    { 
     return (Brush)obj.GetValue(ButtonBorderColourProperty); 
    } 

    public static void SetButtonBorderColour(DependencyObject obj, Brush value) 
    { 
     obj.SetValue(ButtonBorderColourProperty, value); 
    } 

    public static readonly DependencyProperty ButtonBorderColourProperty = 
     DependencyProperty.RegisterAttached(
      "ButtonBorderColour", 
      typeof(Brush), 
      typeof(ThemeProperties), 
      new FrameworkPropertyMetadata(Brushes.Black, FrameworkPropertyMetadataOptions.Inherits)); 
} 

tôi thiết lập thuộc tính như sau:

<Button Style="{StaticResource RedButton}" local:ThemeProperties.ButtonBorderColour="#B20000"/> 

Và phong cách của tôi trông như thế này:

<Window.Resources> 
    <Style x:Key="RedButton" TargetType="Button"> 
     <Setter Property="OverridesDefaultStyle" Value="True"/> 
     <Setter Property="Margin" Value="2"/> 
     <Setter Property="FontFamily" Value="Tahoma"/> 
     <Setter Property="FontSize" Value="11px"/> 
     <Setter Property="FontWeight" Value="Bold"/> 
     <Setter Property="Foreground" Value="White"/> 
     <Setter Property="MinHeight" Value="25" /> 

     <Setter Property="FocusVisualStyle" Value="{StaticResource MyFocusVisual}" /> 
     <Setter Property="Background" > 
      <Setter.Value> 
       <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" > 
        <GradientStop Color="#FECCBF" Offset="0.2"/> 
        <GradientStop Color="Red" Offset="0.85"/> 
        <GradientStop Color="#FECCBF" Offset="1"/> 
       </LinearGradientBrush> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="Button"> 
        <Border Name="border" BorderThickness="1" Padding="4,2" BorderBrush="Transparent" CornerRadius="3" Background="{TemplateBinding Background}"> 
         <Grid > 
          <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Name="content"/> 
         </Grid> 
        </Border> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsMouseOver" Value="True"> 
          <Setter TargetName="border" Property="BorderBrush" Value="{TemplateBinding local:ThemeProperties.ButtonBorderColour}" /> 
          <Setter Property="Foreground" Value="#B20000" /> 
         </Trigger> 
         <Trigger Property="IsPressed" Value="True"> 
          <Setter Property="Background" > 
           <Setter.Value> 
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" > 
             <GradientStop Color="#FECCBF" Offset="0.35"/> 
             <GradientStop Color="Red" Offset="0.95"/> 
             <GradientStop Color="#FECCBF" Offset="1"/> 
            </LinearGradientBrush> 
           </Setter.Value> 
          </Setter> 
          <Setter TargetName="content" Property="RenderTransform" > 
           <Setter.Value> 
            <TranslateTransform Y="1.0" /> 
           </Setter.Value> 
          </Setter> 
         </Trigger> 
         <Trigger Property="IsDefaulted" Value="True"> 
          <Setter TargetName="border" Property="BorderBrush" Value="#B20000" /> 
         </Trigger> 
         <Trigger Property="IsFocused" Value="True"> 
          <Setter TargetName="border" Property="BorderBrush" Value="#B20000" /> 
         </Trigger> 
         <Trigger Property="IsEnabled" Value="False"> 
          <Setter TargetName="border" Property="Opacity" Value="0.7" /> 
          <Setter Property="Foreground" Value="Gray" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 

đâu dòng chủ chốt là

<Trigger Property="IsMouseOver" Value="True"> 
    <Setter TargetName="border" Property="BorderBrush" Value="{TemplateBinding local:ThemeProperties.ButtonBorderColour}" /> 
    <Setter Property="Foreground" Value="#B20000" /> 
</Trigger> 

Theo như tôi có thể thấy điều này nên làm việc nhưng tôi nhận được lỗi sau trong thời gian chạy trên dòng trên:

Không thể chuyển đổi các giá trị trong thuộc tính 'Giá trị' để đối tượng của loại ''. Lỗi tại đối tượng 'System.Windows.Setter' trong tệp đánh dấu

Tôi đã làm điều gì đó không chính xác ở đây? Tôi là thương hiệu mới để WPF và không thể hình những gì đang xảy ra như là loại tài sản kèm theo là một Brush đó là những gì tôi mong đợi bất động sản BorderBrush của một biên giới muốn.

Trả lời

39

Tôi nghĩ TemplateBinding được đánh giá tại thời gian biên dịch, do đó bạn không thể tự động đặt một TemplateBinding trong Setter của mình, hãy thử sử dụng Binding (xem bên dưới).

<Setter TargetName="border" Property="BorderBrush" 
     Value="{Binding Path=(local:ThemeProperties.ButtonBorderColour), 
         RelativeSource={RelativeSource TemplatedParent}}"/> 

Hy vọng điều này sẽ hữu ích.

+0

Hey tôi đã chỉnh sửa câu trả lời của mình, nó sẽ hoạt động ngay bây giờ. Đó là một lỗi cú pháp, xin lỗi về điều đó. –

+0

Cảm ơn XiaoChuan, đã hoạt động hoàn hảo. Tôi cũng có thể thấy sự khác biệt giữa mã của tôi và ví dụ trên trang web được liên kết vì ví dụ này không sử dụng TemplateBinding trong trình thiết lập mà tôi không đánh giá cao trước đây. Cảm ơn một lần nữa! – thudbutt

+0

Tôi không hiểu tại sao trường hợp giống hệt nhau của tôi không hoạt động trong thời gian thiết kế (nhưng nó hoạt động trong thời gian chạy) - http://stackoverflow.com/questions/41614676/binding-style-property-value-to-an-attached -property-cause-design-time-only-e/41617979 –

1

Hãy thử điều này:

<Setter TargetName="border" Property="BorderBrush" Value="{TemplateBinding Path=(local:ThemeProperties.ButtonBorderColour)}" /> 

Sự khác biệt là ngoặc xung quanh tài sản chỉ ra rằng nó là một tài sản gắn liền.

+0

Thật không may là dường như không được công nhận là cú pháp hợp lệ và nó chỉ trả về lỗi Type '(local: ThemeProperties' không được tìm thấy. – thudbutt

+2

Xin lỗi, bạn cần 'Path =' ở phía trước nó. –

+0

Vẫn không có niềm vui, vẫn bị gắn cờ là cú pháp không hợp lệ với lỗi "Thuộc tính 'Đường dẫn' không được tìm thấy trong loại 'TemplateBindingExtension'". – thudbutt

Các vấn đề liên quan