2010-10-20 63 views
13

我的WPF應用程序有一個我在混合基礎上構建的樣式管理器。WPF應用程序上的閃爍按鈕

我的問題是這樣的:我有一個偶爾閃爍的登錄按鈕,我無法弄清楚如何刪除此行爲。

下面是我的登陸框樣式代碼:

<Style x:Key="LoginBoxGrid" TargetType="{x:Type Grid}"> 
    <Setter Property="Background"> 
     <Setter.Value> 
      <ImageBrush ImageSource="/Client;component/Assets/images/LoginBox.png" Stretch="None" TileMode="Tile"/> 
     </Setter.Value> 
    </Setter> 

    <Setter Property="Opacity" Value="0.765"/> 
    <Setter Property="Width" Value="411"/> 
    <Setter Property="HorizontalAlignment" Value="Left"/> 
    <Setter Property="Margin" Value="126,150,0,111"/> 
</Style> 
<Style x:Key="LoginBoxHeader" TargetType="{x:Type Label}"> 
    <Setter Property="Grid.Column" Value="2"/> 
    <Setter Property="Margin" Value="-16.183,18.347,0,0"/> 
    <Setter Property="Width" Value="64.994"/> 
    <Setter Property="FontSize" Value="16"/> 
    <Setter Property="FontWeight" Value="Bold"/> 
    <Setter Property="FontStyle" Value="Italic"/> 
    <Setter Property="Foreground" Value="White"/> 
    <Setter Property="VerticalAlignment" Value="Top"/> 
    <Setter Property="HorizontalAlignment" Value="Left"/> 
    <Setter Property="FontFamily" Value="/Client;component/Assets/Fonts/#Arial Black"/> 
</Style> 

<Style x:Key="LoginBtn" TargetType="{x:Type Button}"> 
    <Setter Property="Grid.Column" Value="2"/> 
    <Setter Property="Margin" Value="16.6,9.022,9.282,8"/> 
    <Setter Property="Grid.Row" Value="4"/> 
    <Setter Property="Width" Value="164"/> 
    <Setter Property="BorderThickness" Value="0"/> 
    <Setter Property="Opacity" Value="0.78"/> 
    <Setter Property="IsDefault" Value="True"/> 
    <Setter Property="Foreground" Value="White"/> 
    <Setter Property="Background"> 
     <Setter.Value> 
      <ImageBrush ImageSource="/Client;component/Assets/images/LoginBtn.png"/> 
     </Setter.Value> 
    </Setter> 
</Style> 

而且這裏是我的窗口代碼:

<Grid Style="{StaticResource LoginBoxGrid}" > 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="0.127*"/> 
      <ColumnDefinition Width="0.326*"/> 
      <ColumnDefinition Width="0.462*"/> 
      <ColumnDefinition Width="0.085*"/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="0.269*"/> 
      <RowDefinition Height="0.028*"/> 
      <RowDefinition Height="0.256*"/> 
      <RowDefinition Height="0.223*"/> 
      <RowDefinition Height="0.178*"/> 
      <RowDefinition Height="0.046*"/> 
     </Grid.RowDefinitions> 
     <Label Content="User Name" Grid.Column="1" Margin="43.986,23.1,8,8" Grid.Row="2" Width="82" BorderThickness="0" FontFamily="Arial" FontWeight="Bold" FontStyle="Italic"/> 
     <Label Content="Password" Grid.Column="1" Margin="43.986,15.873,8,8" Grid.Row="3" Width="82" BorderThickness="0" FontFamily="Arial" FontWeight="Bold" FontStyle="Italic"/> 
     <PasswordBox Grid.Column="2" Name="PassTb" HorizontalAlignment="Left" Margin="8,18.877,0,8" Grid.Row="3" Width="172.6" d:LayoutOverrides="Height"/> 
     <TextBox Grid.Column="2" Name="UserTb" HorizontalAlignment="Left" Margin="9.282,23.1,0,11.004" Grid.Row="2" TextWrapping="Wrap" Text="TextBox" Width="172.6" d:LayoutOverrides="Height"/> 
     <Label Style="{StaticResource LoginBoxHeader}" Content="Login" /> 
     <Button Name="LoginBtn" Style="{StaticResource LoginBtn}" Content="Login" /> 
    </Grid> 

我說的是被稱爲「LoginBtn」的按鈕,是它的風格。

如何消除閃爍行爲?提前致謝。

+0

@ user481711:將其更改爲c# – yadab 2010-10-20 13:27:02

+0

您可以更好地定義「閃爍」。你的意思是它不斷在兩種視覺狀態之間切換,還是由鼠標懸停等事件觸發? – Val 2010-10-21 05:31:06

回答

1

我從我的第一個答案遇到這個問題時,將圖像附加到按鈕,我想通過設置圖像和按鈕來拉伸和使用邊界上的大小它解決了問題。

示例代碼..

<Border Width="45" Height="45"> 
          <Button x:Name="buttonSend" 
           ToolTip="Send" Command="{Binding Path=SendCommand}" Style="{StaticResource actionButtonStyle}"> 
           <Image Source="..\Images\Email-256.png" Stretch="Fill" /> 
          </Button> 
9

中閃爍的是由於使用WPF爲按鈕的默認樣式。更具體地說,這是由於按鈕控件模板上的觸發器。要刪除它,請進入混合,右鍵單擊該按鈕並選擇「編輯模板」 - >「編輯一個副本」。點擊內容展示者的子元素(默認情況下,這是名爲「Chrome」的控件)。然後,在觸發器選項卡中,通過按「 - 觸發器」,非活動RenderDefaulted。該觸發器將保持按鈕不閃爍。如果你只是想爲所有的XAML,這是由windows.resource包裹...

<Window.Resources> 
    <Style x:Key="ButtonFocusVisual"> 
     <Setter Property="Control.Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 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="#FF707070"/> 
    <Style x:Key="BoringButtonStyle" TargetType="{x:Type Button}"> 
     <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="{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}"> 
        <Microsoft_Windows_Themes:ButtonChrome 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}"/> 
        </Microsoft_Windows_Themes:ButtonChrome> 
        <ControlTemplate.Triggers> 
         <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> 

然後,無論你按鈕,將此風格。

<Button Style="{DynamicResource BoringButtonStyle}"/> 

更新:多年來默認的按鈕樣式發生了變化。這個想法是一樣的,使用Blend for Visual Studio來編輯你想要改變的元素的模板。對於這個按鈕,只需簡單地刪除IsDefaulted觸發器。這是一個更新的代碼片段。

<Style x:Key="FocusVisual"> 
     <Setter Property="Control.Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/> 
    <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/> 
    <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/> 
    <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/> 
    <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/> 
    <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/> 
    <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/> 
    <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/> 
    <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/> 
    <Style x:Key="BoringButtonStyle" TargetType="{x:Type Button}"> 
     <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/> 
     <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/> 
     <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/> 
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
     <Setter Property="BorderThickness" Value="1"/> 
     <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}"> 
        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> 
         <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
        </Border> 
        <ControlTemplate.Triggers> 
         <!-- Delete this trigger 
         <Trigger Property="IsDefaulted" Value="true"> 
          <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 
         </Trigger>--> 
         <Trigger Property="IsMouseOver" Value="true"> 
          <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/> 
          <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/> 
         </Trigger> 
         <Trigger Property="IsPressed" Value="true"> 
          <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/> 
          <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/> 
         </Trigger> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/> 
          <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/> 
          <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
+2

工程就像一個魅力。感謝您的描述,我們可以右鍵單擊並編輯模板副本,這非常有幫助。 – MasterMastic 2012-10-09 18:24:40

+0

不起作用,我沒有任何內容展示器的子元素,也沒有「chrome」或「RenderDefaulted」。 – 2017-11-09 12:35:36

+0

自2011年以來看起來情況已發生變化。沒有Microsoft_Windows_Themes:ButtonChrome控件了。現在您可以完全刪除IsDefaulted觸發器。我會更新我的答案以反映這些變化。 – Onosa 2017-11-14 22:30:41

9

簡單的解決方案:將按鈕的「Focusable」設置爲False。

+12

只要你正在處理鍵盤導航,這就會打開一罐蠕蟲... – Jan 2011-05-11 13:42:51

+3

它更像是如果你頭痛的時候砍頭。 – Marshal 2015-06-12 14:58:05

5

刪除閃爍的稍微不顯眼的方法是設置新的ControlTemplateButtonBase刪除違規綁定。

我通過StyleSnooper從Button默認的Style中取得了這個樣式,並將它改造/簡化爲ButtonBase的Style,它只是提供了一個新的ControlTemplate *。爲此,請在Presentation.Aero中添加一個程序集引用,並在ResourceDictionary中引入Microsoft.Windows.Themes命名空間。

在這裏,我明確地刪除了受影響的Button在其IsDefault屬性上「閃爍」的能力,通過將RenderDefaulted硬編碼爲false;你可能也想更換RenderMouseOver TemplateBinding。

<ResourceDictionary [...] 
       xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"> 

<Style TargetType="{x:Type ButtonBase}" 
     x:Key="NonBlinkingButtonBase"> 
    <Setter Property="Control.Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ButtonBase}"> 
       <mwt:ButtonChrome Background="{TemplateBinding Panel.Background}" 
            BorderBrush="{TemplateBinding Border.BorderBrush}" 
            RenderDefaulted="False" 
            RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}" 
            RenderPressed="{TemplateBinding ButtonBase.IsPressed}" 
            Name="Chrome" 
            SnapsToDevicePixels="True"> 
        <ContentPresenter RecognizesAccessKey="True" 
             Content="{TemplateBinding ContentControl.Content}" 
             ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" 
             ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" 
             Margin="{TemplateBinding Control.Padding}" 
             HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" 
             VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" 
             SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> 
       </mwt:ButtonChrome> 
       <ControlTemplate.Triggers> 
        <Trigger Property="UIElement.IsKeyboardFocused" Value="True"> 
         <Setter Property="mwt:ButtonChrome.RenderDefaulted" TargetName="Chrome" Value="True" /> 
        </Trigger> 
        <Trigger Property="ToggleButton.IsChecked" Value="True"> 
         <Setter Property="mwt:ButtonChrome.RenderPressed" TargetName="Chrome" Value="True" /> 
        </Trigger> 
        <Trigger Property="UIElement.IsEnabled" Value="False"> 
         <Setter Property="TextElement.Foreground"> 
          <Setter.Value> 
           <SolidColorBrush> 
            #FFADADAD</SolidColorBrush> 
          </Setter.Value> 
         </Setter> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

然後用這個風格爲支持算法FMP您的按鈕:

<Style x:Key="LoginBtn" 
     TargetType="{x:Type Button}" 
     BasedOn="{StaticResource NonBlinkingButtonBase}"> 
[...your stuff...] 
</Style> 

(*)是的,我們確實應該要使用支持算法FMP的CONTROLTEMPLATES以及能力...