2016-10-06 45 views
3

我在Xamarin Forms項目的App.xaml中定義了一些樣式。但是,如果將鼠標懸停在按鈕上或按下它,則不會影響該按鈕。字體顏色會在此處變爲黑色,並出現按鈕周圍的灰色邊框。現在我想覆蓋這種風格。Xamarin.Forms:在UWP中懸停時自定義按鈕樣式

首先嚐試:添加定義到UWP項目

<Application 
    x:Class="YourApp.UWP.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:YourApp.UWP" 
    RequestedTheme="Light"> 

    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.ThemeDictionaries> 
       <ResourceDictionary x:Key="Light"> 
        <SolidColorBrush x:Key="ButtonPointerOverBackgroundThemeBrush" Color="#00FF00" /> 
       </ResourceDictionary> 
      </ResourceDictionary.ThemeDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

結果的App.xaml:在所有

二沒有改變嘗試:在UWP項目App.xaml覆蓋PointOver可視狀態

<Application 
    x:Class="YourApp.UWP.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:YourApp.UWP" 
    RequestedTheme="Light"> 

    <Application.Resources> 
     <ResourceDictionary> 
      <Style TargetType="Button" x:Key="HoverButtonStyle"> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="Button"> 
          <Grid> 
           <VisualStateManager.VisualStateGroups> 
            <VisualStateGroup x:Name="CommonStates"> 
             <VisualState x:Name="PointerOver"> 
              <Storyboard> 
               <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border" 
                       Storyboard.TargetProperty="Background"> 
                <DiscreteObjectKeyFrame KeyTime="0" Value="#00FF00" /> 
               </ObjectAnimationUsingKeyFrames> 
               <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" 
                       Storyboard.TargetProperty="Foreground"> 
                <DiscreteObjectKeyFrame KeyTime="0" Value="#00FF00" /> 
               </ObjectAnimationUsingKeyFrames> 
              </Storyboard> 
             </VisualState> 
            </VisualStateGroup> 
           </VisualStateManager.VisualStateGroups> 
          </Grid> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

結果:以不變應萬變,我想我有applay風格(如果我這樣做的按鈕似乎不是在這裏)

第三次嘗試:添加完整的按鈕樣式,並將其應用於

<Style TargetType="Button" x:Key="HoverButtonStyle"> 
    <Setter Property="Background" Value="{ThemeResource ButtonBackgroundThemeBrush}" /> 
    <Setter Property="Foreground" Value="{ThemeResource ButtonForegroundThemeBrush}"/> 
    <Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderThemeBrush}" /> 
    <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" /> 
    <Setter Property="Padding" Value="12,4,12,4" /> 
    <Setter Property="HorizontalAlignment" Value="Left" /> 
    <Setter Property="VerticalAlignment" Value="Center" /> 
    <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" /> 
    <Setter Property="FontWeight" Value="SemiBold" /> 
    <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="Button"> 
       <Grid> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualState x:Name="Normal" /> 
          <VisualState x:Name="PointerOver"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border" 
                 Storyboard.TargetProperty="Background"> 
             <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPointerOverBackgroundThemeBrush}" /> 
            </ObjectAnimationUsingKeyFrames> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" 
                 Storyboard.TargetProperty="Foreground"> 
             <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPointerOverForegroundThemeBrush}" /> 
            </ObjectAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Pressed"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border" 
                 Storyboard.TargetProperty="Background"> 
             <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedBackgroundThemeBrush}" /> 
            </ObjectAnimationUsingKeyFrames> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" 
                 Storyboard.TargetProperty="Foreground"> 
             <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedForegroundThemeBrush}" /> 
            </ObjectAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Disabled"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border" 
                 Storyboard.TargetProperty="Background"> 
             <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonDisabledBackgroundThemeBrush}" /> 
            </ObjectAnimationUsingKeyFrames> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border" 
                 Storyboard.TargetProperty="BorderBrush"> 
             <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonDisabledBorderThemeBrush}" /> 
            </ObjectAnimationUsingKeyFrames> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" 
                 Storyboard.TargetProperty="Foreground"> 
             <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonDisabledForegroundThemeBrush}" /> 
            </ObjectAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
         <VisualStateGroup x:Name="FocusStates"> 
          <VisualState x:Name="Focused"> 
           <Storyboard> 
            <DoubleAnimation Storyboard.TargetName="FocusVisualWhite" 
             Storyboard.TargetProperty="Opacity" 
             To="1" 
             Duration="0" /> 
            <DoubleAnimation Storyboard.TargetName="FocusVisualBlack" 
             Storyboard.TargetProperty="Opacity" 
             To="1" 
             Duration="0" /> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Unfocused" /> 
          <VisualState x:Name="PointerFocused" /> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <Border x:Name="Border" 
       Background="{TemplateBinding Background}" 
       BorderBrush="{TemplateBinding BorderBrush}" 
       BorderThickness="{TemplateBinding BorderThickness}" 
       Margin="3"> 
         <ContentPresenter x:Name="ContentPresenter" 
           Content="{TemplateBinding Content}" 
           ContentTransitions="{TemplateBinding ContentTransitions}" 
           ContentTemplate="{TemplateBinding ContentTemplate}" 
           Margin="{TemplateBinding Padding}" 
           HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
           VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
           AutomationProperties.AccessibilityView="Raw"/> 
        </Border> 
        <Rectangle x:Name="FocusVisualWhite" 
        IsHitTestVisible="False" 
        Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}" 
        StrokeEndLineCap="Square" 
        StrokeDashArray="1,1" 
        Opacity="0" 
        StrokeDashOffset="1.5" /> 
        <Rectangle x:Name="FocusVisualBlack" 
        IsHitTestVisible="False" 
        Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}" 
        StrokeEndLineCap="Square" 
        StrokeDashArray="1,1" 
        Opacity="0" 
        StrokeDashOffset="0.5" /> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

自定義渲染:

protected override void OnElementChanged(ElementChangedEventArgs<Button> e) 
{ 
    base.OnElementChanged(e); 

    if (this.Element != null) 
    { 
     this.Control.Style = Windows.UI.Xaml.Application.Current.Resources["HoverButtonStyle"] as Windows.UI.Xaml.Style; 
    } 
} 

結果:風格似乎也適用,但我在Xamarin形式定義的背景顏色不走按鈕的整個寬度。此外邊框顏色仍然沒有改變。

這是怎麼做到的?

回答

3

現在我發現了這種造型的工作原理。首先,您必須找到基本的UWP類(通過按住Ctrl並單擊課程名稱或查看here)。例如。對於Picker它是ComboBox。如果你使用Google,你可以到this page,在那裏你可以找到你需要知道的關於覆蓋ComboBox的默認佈局的所有信息。對於Button,它是this page等。因此,解決辦法是有一個App.xaml(UWP項目)像這樣(把你所選擇的顏色):

<Application 
    x:Class="YourApp.UWP.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:YourApp.UWP" 
    RequestedTheme="Light"> 

    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.ThemeDictionaries> 
       <ResourceDictionary x:Key="Light"> 
        <SolidColorBrush x:Key="SystemControlHighlightBaseMediumLowBrush" Color="White" /> 
        <SolidColorBrush x:Key="SystemControlHighlightBaseHighBrush" Color="White" /> 
       </ResourceDictionary> 
      </ResourceDictionary.ThemeDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

只對某些按鈕應用樣式,你必須做以下步驟:

在你UWP項目App.xaml您需要輸入以下內容:

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="Styles/DefaultButtonControlTemplate.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

在這裏您註冊一個風格,這是在一個單獨的文件。我有一個名爲Styles文件夾,其中DefaultButtonControlTemplate.xaml被放置在從MSDN採取的文件的內容,看起來像這樣的文件:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:MyApp.UWP.ControlTemplates"> 

    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="ColorsAndBrushes.xaml" /> 
    </ResourceDictionary.MergedDictionaries> 

    <ControlTemplate x:Key="DefaultButtonControlTemplate" TargetType="Button"> 
     <!-- here is the content of the file --> 
    </ControlTemplate> 

</ResourceDictionary> 

正如你可以看到我引用一個共同文件,其中包含我所有的顏色(或UWP世界中的畫筆)。

最後,你需要自定義呈現這樣的:

public class DefaultButtonRenderer : ButtonRenderer 
{ 
    protected override void OnElementChanged(ElementChangedEventArgs<Button> e) 
    { 
     base.OnElementChanged(e); 

     if (this.Control != null) 
     { 
      this.Control.Template = Windows.UI.Xaml.Application.Current.Resources["DefaultButtonControlTemplate"] as Windows.UI.Xaml.Controls.ControlTemplate; 
     } 
    } 
} 
+0

如果你只是想將它應用到一些按鈕是什麼? – SuperJMN

+0

我找到的一種方法是使用自定義渲染器(請參閱編輯答案)。不知道是否有更好/更簡單的方法。 – testing