2010-12-29 51 views
10

Tôi đã theo dõi ChrisFhere và viết simple demo.Làm cách nào để xóa đường viền ButtonChrome (khi xác định mẫu của đường viền)?

... mở dự án của bạn trong Expression Blend, chọn nút và sau đó nhấn chuột phải và chọn "Edit Template> Chỉnh sửa Sao chép ..". Điều này sao chép mẫu hiện có vào mẫu mà bạn có thể sửa đổi. Đó là dễ dàng hơn nếu bạn tạo nó trong một tài nguyên từ điển.

Và tôi có thể thấy mẫu đằng sau màn hình của nút như bên dưới ảnh chụp màn hình (The ButtonChrome trong tài nguyên).

Tôi muốn xóa đường viền màu trắng-gradient của NútChromeVÀ giữ mọi thứ khác trong giao diện người dùng của nút vẫn giữ nguyên là. Làm thế nào tôi có thể làm điều đó?

ps. Để làm cho vấn đề trở nên đơn giản, tôi sử dụng ButtonChrome như một điều khiển bình thường trên quan điểm của tôi. Tôi duyệt các thuộc tính nhưng vẫn không có ý tưởng nơi để loại bỏ các "trắng" biên giới.

(The ButtonChrome trong sử dụng) alt text

(Các ButtonChrome trong Resource) alt text

Trả lời

10

Tôi không nghĩ rằng có một cách dễ dàng để thoát khỏi rằng trắng Border. Các thói quen thực tế được gọi là DrawInnerBorder và được gọi từ bên trong OnRender trong ButtonChrome.

protected override void OnRender(DrawingContext drawingContext) 
{ 
    Rect bounds = new Rect(0.0, 0.0, base.ActualWidth, base.ActualHeight); 
    this.DrawBackground(drawingContext, ref bounds); 
    this.DrawDropShadows(drawingContext, ref bounds); 
    this.DrawBorder(drawingContext, ref bounds); 

    // This one draws the white Rectangle 
    this.DrawInnerBorder(drawingContext, ref bounds); 
} 

private void DrawInnerBorder(DrawingContext dc, ref Rect bounds) 
{ 
    if ((base.IsEnabled || this.RoundCorners) && ((bounds.Width >= 4.0) && (bounds.Height >= 4.0))) 
    { 
     Pen innerBorderPen = this.InnerBorderPen; 
     if (innerBorderPen != null) 
     { 
      dc.DrawRoundedRectangle(null, innerBorderPen, new Rect(bounds.Left + 1.5, bounds.Top + 1.5, bounds.Width - 3.0, bounds.Height - 3.0), 1.75, 1.75); 
     } 
    } 
} 

Như chúng ta có thể thấy, không có thuộc tính để tắt tính năng này. Bạn có thể xác minh bằng cách đặt IsEnabled="False"RoundCorners="False" trên ButtonChrome hoặc bằng cách đặt Chiều rộng hoặc Chiều cao thành khoảng 3,99 và "Đường viền màu trắng" biến mất.

Cập nhật
Để tắt đường viền bên trong của ButtonChrome, bạn có thể tạo ButtonChrome của riêng bạn để thêm thuộc tính này. Thật không may ButtonChrome được niêm phong vì vậy chúng tôi không thể kế thừa từ nó. Tôi đã cố gắng để sao chép toàn bộ lớp và thêm Property DisableInnerBorder và nó có vẻ là làm việc.Bạn có thể sử dụng nó như thế này

<local:MyButtonChrome ... 
         DisableInnerBorder="True"> 

Khác hơn là nó hoạt động giống như ButtonChrome thông thường và bạn cũng có thể thêm các Thuộc tính khác mà bạn có thể muốn. Có thể có những hạn chế đối với phương pháp này mà tôi đã không nghĩ đến, nhưng đối với một thử nghiệm nhỏ, nó hoạt động tốt.

apperently 937 dòng mã là quá nhiều để viết về SO :) Tôi đã tải lên MyButtonChrome.cs đây: http://www.mediafire.com/?wnra4qj4qt07wn6

+0

Bạn có thể lấy mã này bằng cách nào? Nó surpises tôi :) –

+0

@Nam Gi VU: Tôi đã sử dụng .NET Reflector và thêm vào Assembly PresentationFramework.Aero để gỡ lỗi. Sau đó, tôi chỉ cần bước qua các thói quen vẽ để tìm ra nơi này đã được rút ra và kiểm tra nếu có một số cách để vô hiệu hóa nó :) –

+0

Cảm ơn bạn Meleak! Giới thiệu về đề xuất của bạn để sử dụng 'Border' thay vì' ButtonChrome', tôi sẽ mất tất cả hiệu ứng giao diện người dùng của một nút thông thường (di chuột qua, nhấn, ect.) Bạn có bất kỳ công việc nào không? –

4

Bạn không nên cố gắng để tùy chỉnh ButtonChrome. * Lớp Chrome đặc trưng theo chủ đề, tức là chúng chứa triển khai chủ đề cửa sổ cụ thể và bạn không thể ghi đè lên nó. Nhìn vào khai báo của không gian tên "Microsoft_Windows_Themes" trong từ điển tài nguyên của bạn - nó có thể chứa một cái gì đó như PresentationFramework.Aero ...

Những gì bạn cần làm trong các mẫu tùy chỉnh của bạn là sử dụng Border thông thường thay cho ButtonChrome và xác định trình kích hoạt thay đổi nền của nó, vv khi nút được nhấn hoặc di chuột.

Dưới đây là một ví dụ:

<Style x:Key="BaseButtonStyle" 
    TargetType="{x:Type ButtonBase}"> 
<Setter Property="FocusVisualStyle" 
     Value="{StaticResource ButtonFocusVisual}" /> 
<Setter Property="Background" 
     Value="{StaticResource ButtonNormalBackground}" /> 
<Setter Property="BorderBrush" 
     Value="{StaticResource ButtonNormalBorder}" /> 
<Setter Property="BorderThickness" 
     Value="1" /> 
<Setter Property="Foreground" 
     Value="{StaticResource ButtonNormalForeground}" /> 
<Setter Property="HorizontalContentAlignment" 
     Value="Center" /> 
<Setter Property="VerticalContentAlignment" 
     Value="Center" /> 
<Setter Property="Padding" 
     Value="5,2,5,2" /> 
<Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type ButtonBase}"> 
      <Border Name="Chrome" 
        Background="{TemplateBinding Background}" 
        BorderBrush="{TemplateBinding BorderBrush}" 
        BorderThickness="{TemplateBinding BorderThickness}" 
        SnapsToDevicePixels="true" 
        CornerRadius="2"> 
       <ContentPresenter Margin="{TemplateBinding Padding}" 
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
            RecognizesAccessKey="True" 
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> 
      </Border> 
      <ControlTemplate.Triggers> 
       <Trigger Property="IsMouseOver" 
         Value="True"> 
        <Setter Property="Background" 
          Value="{StaticResource ButtonHoverBackground}" /> 
        <Setter Property="Foreground" 
          Value="{StaticResource ButtonHoverForeground}" /> 
       </Trigger> 

       <Trigger Property="IsPressed" 
         Value="True"> 
        <Setter Property="Background" 
          Value="{StaticResource ButtonPressedBackground}" /> 
        <Setter Property="Foreground" 
          Value="{StaticResource ButtonPressedForeground}" /> 
       </Trigger> 
       <Trigger Property="ToggleButton.IsChecked" 
         Value="True"> 
        <Setter Property="Background" 
          Value="{StaticResource ButtonHoverBackground}" /> 
        <Setter Property="Foreground" 
          Value="{StaticResource ButtonNormalForeground}" /> 
       </Trigger> 
       <Trigger Property="IsEnabled" 
         Value="false"> 
        <Setter Property="Foreground" 
          Value="#ADADAD" /> 
       </Trigger> 
      </ControlTemplate.Triggers> 
     </ControlTemplate> 
    </Setter.Value> 
</Setter> 

+0

Bạn có thể cung cấp cho tôi mẫu đầy đủ giúp giữ tất cả tính năng giao diện người dùng của một nút ngoại trừ "đường viền màu trắng" không? –

0

nếu bạn muốn chỉ cần tránh các WhiteBorder bạn phải chỉ cần thay đổi BorderBrush = Transparent

<Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" SnapsToDevicePixels="true" 
         Background="{TemplateBinding Background}" BorderBrush="Transparent" 
         RenderDefaulted="{TemplateBinding IsDefaulted}" RenderMouseOver="{TemplateBinding IsMouseOver}" 
          RenderPressed="{TemplateBinding IsPressed}"> 
          <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/> 
         </Microsoft_Windows_Themes:ButtonChrome> 

Nếu bạn muốn thay đổi một số thứ khác bạn phải tạo ControlTemplate của riêng bạn

xin vui lòng liên kết này

http://mark-dot-net.blogspot.com/2007/07/creating-custom-wpf-button-template-in.html

đây họ có nút mẫu khác nhau

+0

@Kumar: Bạn đã thử đề xuất của mình chưa? Nó không hoạt động. –

16

Một trong những fetatures vĩ đại của WPF là khả năng tận dụng hành vi của một điều khiển trong khi hoàn toàn trao đổi giao diện của control.You rằng chỉ có thể xóa hoàn toàn và chrome tạo ra một sự xuất hiện tùy chỉnh phù hợp với yêu cầu của bạn.

mẫu

<Style x:Key="NoChromeButton" TargetType="{x:Type Button}"> 
     <Setter Property="Background" Value="Transparent"/> 
     <Setter Property="BorderThickness" Value="1"/> 
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
     <Setter Property="HorizontalContentAlignment" Value="Center"/> 
     <Setter Property="VerticalContentAlignment" Value="Center"/> 
     <Setter Property="Padding" Value="1"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type Button}"> 
        <Grid x:Name="Chrome" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> 
         <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Foreground" Value="#ADADAD"/> 
          <Setter Property="Opacity" TargetName="Chrome" Value="0.5"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

Kiểm tra này quá http://www.designerwpf.com/2008/03/27/wpf-designers-guide-to-styles-and-templates/

Liên kết này dường như làm việc bây giờ: http://www.designersilverlight.com/2008/03/27/wpf-designers-guide-to-styles-and-templates/

+0

Cảm ơn bạn rất nhiều! –

0

Asfter thảo luận với Meleak trong một thời gian, cuối cùng tôi nhận được giải pháp cuối cùng cho câu hỏi của tôi! Cảm ơn bạn Meleak!

Bạn có thể tải xuống solution source codes here.

1

Tôi nhận ra đây là một chuỗi cũ, nhưng tôi đã tìm thấy nó khi tôi đang cố gắng làm điều tương tự và không tìm thấy bất kỳ giải pháp tuyệt vời nào. Tôi nghĩ rằng tôi sẽ đăng những gì tôi đã đưa ra trong trường hợp nó giúp bất cứ ai khác.

Điều tôi muốn là các nút phẳng sử dụng chrome thông thường khi được kết hợp. Cách tốt nhất tôi có thể tìm thấy để làm điều này là lừa đảo và sử dụng hai ContentPresenters bên trong một Grid với hai hàng. Một người trình bày nội dung nằm bên trong ButtonChrome bình thường và một bên trong một Border. Chỉ có một hàng lưới được hiển thị tại một thời điểm và setter trong kích hoạt IsMouseOver xác định cái nào được hiển thị.

<Window.Resources> 
    <Style x:Key="ButtonFocusVisual"> 
     <Setter Property="Control.Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Rectangle StrokeDashArray="1 2" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" Margin="2"/> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0"> 
     <GradientStop Color="#F3F3F3" Offset="0"/> 
     <GradientStop Color="#EBEBEB" Offset="0.5"/> 
     <GradientStop Color="#DDDDDD" Offset="0.5"/> 
     <GradientStop Color="#CDCDCD" Offset="1"/> 
    </LinearGradientBrush> 
    <SolidColorBrush x:Key="ButtonNormalBorder" Color="Transparent"/> 
    <Style x:Key="ActionButtonStyle" TargetType="{x:Type Button}"> 
     <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/> 
     <Setter Property="Background" Value="{x:Null}"/> 
     <Setter Property="BorderBrush" Value="{x:Null}"/> 
     <Setter Property="BorderThickness" Value="0"/> 
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
     <Setter Property="HorizontalContentAlignment" Value="Center"/> 
     <Setter Property="VerticalContentAlignment" Value="Center"/> 
     <Setter Property="Padding" Value="1"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type Button}"> 
        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition x:Name="ContentWithChrome" Height="0"></RowDefinition> 
          <RowDefinition x:Name="ContentWithBorder" Height="Auto"></RowDefinition> 
         </Grid.RowDefinitions> 
         <Themes:ButtonChrome Grid.Row="0" x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true"> 
          <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
         </Themes:ButtonChrome> 
         <Border Grid.Row="1" Margin="0,2,0,2"> 
          <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
         </Border> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsMouseOver" Value="True"> 
          <Setter Property="Height" TargetName="ContentWithChrome" Value="Auto" /> 
          <Setter Property="Height" TargetName="ContentWithBorder" Value="0" /> 
         </Trigger> 
         <Trigger Property="IsKeyboardFocused" Value="true"> 
          <Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/> 
         </Trigger> 
         <Trigger Property="ToggleButton.IsChecked" Value="true"> 
          <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/> 
         </Trigger> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Foreground" Value="#ADADAD"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 
0

Tùy chọn cũng sử dụng thư viện khác như telerik hoặc xceed (cũng có sẵn để sử dụng thương mại miễn phí). Trong giải pháp của tôi, tôi đã tạo một lớp có nguồn gốc từ Xceed.Wpf.Toolkit.Chromes.ButtonChrome (nút Microsoft ButtonChrome được niêm phong). Trong ResourceDictionary của tôi, tôi đã triển khai một kiểu cho Combobox, được tạo bởi Blend for VS. Trong ControlTemplate cho ToggleButton tôi đã thực hiện đoạn mã sau:

<ControlTemplate TargetType="{x:Type ToggleButton}"> 
    <p:ButtonChromeManaged x:Name="Chrome" 
          Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" 
          Background="Transparent" 
          BorderBrush="Transparent" 
          CornerRadius="0" 
          SnapsToDevicePixels="true"> 
     <p:ButtonChromeManaged.Template> 
      <ControlTemplate TargetType="{x:Type p:ButtonChromeManaged}"> 
       <Border Background="Red"> 
        <Path x:Name="Arrow" 
          Margin="0,1,0,0" 
          HorizontalAlignment="Center" 
          VerticalAlignment="Center" 
          Data="{StaticResource DownArrowGeometry}" 
          Fill="Black" /> 
       </Border> 
      </ControlTemplate> 
     </p:ButtonChromeManaged.Template> 

đây bạn có thể chỉ thấy stuf impertand nhất. DownArrowGeometry của bạn và như vậy, bạn biết phải làm. Tôi hy vọng điều này có thể giúp ai đó ;-)

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