2010-12-29 20 views
10

Połączyłem się z ChrisFhere i napisałem simple demo.Jak usunąć obramowanie ButtonChrome (przy definiowaniu szablonu obramowania)?

... otwórz projekt w Expression Blend, wybrać przycisk, a następnie kliknij prawym przyciskiem i wybierz „Edytuj szablon> Edycja Kopiuj ..”. To kopiuje istniejący szablon do tego, który można modyfikować. Jest łatwiejsze, jeśli utworzysz go w słowniku zasobu .

I widzę szablon zza ekranu przycisku jak poniżej zrzut ekranu (The ButtonChrome w zasobu).

chcę usunąć biały gradientem granicę ButtonChromei zachować wszystko inne przycisku w interfejsie pozostanie jak jest. Jak mogę to zrobić?

ps. Aby uprościć ten problem, używam ButtonChrome jako normalnej kontroli w moim widoku. Przeglądam nieruchomości, ale nadal nie mam pojęcia, gdzie usunąć "białą" granicę.

(The ButtonChrome w obsłudze) alt text

(ButtonChrome w Zasobu) alt text

Odpowiedz

10

Nie sądzę, istnieje łatwy sposób, aby pozbyć się tego białą obwódkę. Aktualnie wywoływaną procedurą jest DrawInnerBorder i wywoływana z OnRender w 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); 
     } 
    } 
} 

Jak widzimy, nie ma właściwość, aby wyłączyć tę funkcję. Możesz to sprawdzić, ustawiając IsEnabled="False" i RoundCorners="False" na ButtonChrome lub ustawiając Szerokość lub Wysokość na coś podobnego do 3.99 i "Biała ramka" znika.

Aktualizacja
Aby wyłączyć wewnętrzną granicę ButtonChrome można utworzyć własną ButtonChrome która dodaje tę właściwość. Niestety ButtonChrome jest zapieczętowany, więc nie możemy z niego odziedziczyć. Próbowałem skopiować całą klasę i dodać właściwość DisableInnerBorder i wydaje się, że działa.Można go używać jak to

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

Inne niż to, że działa podobnie jak regularne ButtonChrome można także dodać inne właściwości itp, które można chcieć. Mogą być wady tej metody, o których nie myślałem, ale na mały test zadziałał dobrze.

apperently 937 linii kodu było zbyt wiele, aby odpowiedzieć na SO :) upload MyButtonChrome.cs tutaj: http://www.mediafire.com/?wnra4qj4qt07wn6

+0

Jak uzyskać te kody? To mnie dziwi :) –

+0

@Nam Gi VU: Użyłem reflektora .NET i dodałem zespół PresentationFramework.Aero do debugowania. Następnie przejrzałem procedury rysowania, aby dowiedzieć się, gdzie to zostało narysowane i sprawdziłem, czy jest jakiś sposób, aby je wyłączyć :) –

+0

Dziękuję Meleak! O twojej sugestii użycia 'Border' zamiast' ButtonChrome', stracę cały efekt UI normalnego przycisku (przesuwając kursor myszy, wciśnięty, itd.) Czy masz jakieś obejście tego? –

4

Nie należy próbować dostosować ButtonChrome. * Klasy Chrome mają charakter tematyczny, tzn. Zawierają implementację określonego motywu systemu Windows i nie można go przesłonić. Spójrz na deklarację przestrzeni nazw "Microsoft_Windows_Themes" w słowniku zasobów - prawdopodobnie zawiera ona coś w rodzaju PresentationFramework.Aero ...

Co należy zrobić w niestandardowych szablonach, użyj zwykłej ramki Border zamiast ButtonChrome i określ wyzwalacze, które będą zmienić jego tło itp. po naciśnięciu przycisku lub podskakiwaniu.

Oto przykład:

<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

Czy możesz podać pełny szablon, który pomaga zachować funkcję interfejsu użytkownika przycisku oprócz "białej granicy"? –

0

jeśli chcesz po prostu uniknąć WhiteBorder trzeba tylko zmienić 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> 

Jeśli chcesz zmodyfikować kilka innych rzeczy, które trzeba tworzyć własne ControlTemplate

proszę ten link

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

tutaj mają różne szablony przycisk

+0

@Kumar: Czy próbowałeś swojej sugestii? To nie działa. –

16

Jedną z wielkich fetatures WPF jest możliwość wykorzystać zachowanie kontroli podczas wymiany całkowicie wygląd tej control.You można po prostu usunąć całkowicie i Chrome stworzyć niestandardowy wygląd pasujący do Twoich wymagań.

Próbka

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

Sprawdź to zbyt http://www.designerwpf.com/2008/03/27/wpf-designers-guide-to-styles-and-templates/

Ten link wydaje się działać teraz: http://www.designersilverlight.com/2008/03/27/wpf-designers-guide-to-styles-and-templates/

+0

Dziękuję bardzo, bardzo! –

0

Asfter rozmowy z Meleak przez jakiś czas, w końcu mam ostateczne rozwiązanie na moje pytanie! Dziękuję Meleak!

Możesz pobrać solution source codes here.

1

Zdaję sobie sprawę, że jest to stary wątek, ale znalazłem go, gdy próbowałem zrobić to samo i nie znalazłem żadnych wspaniałych rozwiązań. Pomyślałem, że opowiem, co wymyśliłem, na wypadek, gdyby pomogło komukolwiek innemu.

Potrzebowałem płaskich guzików, które używały zwykłego chromu po zmoczeniu. Najlepszym sposobem, jaki mogłem znaleźć, było oszukiwanie i używanie dwóch ContentPresenterów w Gridzie z dwoma wierszami. Jeden z prezenterów zawartości znajduje się w normalnym ButtonChrome, a jeden wewnątrz Border. Wyświetlany jest tylko jeden wiersz siatki, a ustawnik w wyzwalaczu IsMouseOver określa, który z nich jest wyświetlany.

<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

Opcją jest również użycie innej biblioteki, takiej jak telerik lub xceed (dostępna również do bezpłatnego komercyjnego wykorzystania). W moim rozwiązaniu stworzyłem klasę i wyprowadziłem ją z Xceed.Wpf.Toolkit.Chromes.ButtonChrome (ButtonChrome Microsoft jest zapieczętowany). W moim ResourceDictionary zaimplementowałem styl dla Combobox, stworzony przez Blend dla VS. W ControlTemplate dla ToggleButton I wprowadziły następujące kodu:

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

Tutaj można zobaczyć tylko najbardziej impertand stuf. Twoja DownArrowGeometry i tak dalej, wiesz, że do zrobienia. Mam nadzieję, że to może komuś pomóc ;-)

Powiązane problemy