簡體   English   中英

WPF:鼠標在控件上移動時的徑向漸變

[英]WPF: Radial Gradient as Mouse Moves Over a Control

我想一個徑向漸變效果應用到我的按鈕作為對他們鼠標移動的解釋在這里 因此,我有一個單獨的資源文件,用於定義按鈕樣式。

MyButtonStyle.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyTestButtons">
    <Style TargetType="Button" x:Key="MyButtonStyle">
        <!--<Setter Property="Background" Value="Transparent" />-->
        <Setter Property="TextBlock.TextAlignment" Value="Center" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">                   
                    <Border  Name="Border" CornerRadius="0"  
                             BorderBrush="#000" BorderThickness="1,1,1,1" 
                             Background="{TemplateBinding Background}">
                        <ContentPresenter x:Name="contentPresenter" 
                                          ContentTemplate="{TemplateBinding ContentTemplate}" 
                                          Content="{TemplateBinding Content}" 
                                          HorizontalAlignment="{TemplateBinding HorizontalAlignment}" 
                                          Margin="{TemplateBinding Padding}" 
                                          VerticalAlignment="{TemplateBinding VerticalAlignment}" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

我將我的按鈕應用如下。

視窗

<Window x:Class="MyTestButtons"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary  Source="/MyButtonStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

   <Button Name="btnYes" Content="Yes"  
        Margin="3,5" MinWidth="70" Height="35" 
        Click="Button_Click" Foreground="Black" FontSize="14" 
        Style="{StaticResource MyButtonStyle}"  
         VerticalAlignment="Center" 
        HorizontalAlignment="Stretch"  
        VerticalContentAlignment="Center" 
        HorizontalContentAlignment="Center" 
        MouseMove="btnYes_MouseMove" 
        MouseLeave="btnYes_MouseLeave">
    <Button.Background>
        <RadialGradientBrush x:Name="gradRadial" RadiusX="0.25">
            <GradientStop Color="AliceBlue" Offset="0.0"/>
            <GradientStop Color="LightSteelBlue" Offset="1.0"/>
        </RadialGradientBrush>
    </Button.Background>
   </Button>
</Window>

窗口隱藏代碼

    private void btnYes_MouseMove(object sender, MouseEventArgs e)
    {
        Point pt = Mouse.GetPosition(btnYes);
        gradRadial.GradientOrigin = new Point(pt.X / btnYes.Width, pt.Y / btnYes.Height);
        gradRadial.Center = gradRadial.GradientOrigin;
    }

    private void btnYes_MouseLeave(object sender, MouseEventArgs e)
    {
        gradRadial.GradientOrigin = new Point(0.5, 0.5);   // Default
        gradRadial.Center = gradRadial.GradientOrigin;
    }

我的問題和目標是:

  1. 徑向漸變未正確應用。 我的意思是,徑向漸變顯示在我的按鈕的中心而沒有將鼠標放在上方,而當鼠標移到按鈕上方時,徑向漸變始終停留在中心,徑向漸變不是從鼠標懸停的原點生成的,例如提供的鏈接中顯示的三只鼠標的屏幕截圖。
  2. 使用后面的代碼迫使我兩個為每個按鈕創建兩個事件MouseMove和MouseLeave。 我想在不使用代碼的情況下做到這一點,僅使用xaml並將所有代碼放在一個文件中,就在我的樣式文件MyButtonStyle.xaml中。

Fisrt問題的發生是因為:

gradRadial.GradientOrigin = new Point(pt.X / btnYes.Width, pt.Y / btnYes.Height);

您使用了btnYes.Width但是沒有為按鈕設置此屬性,並且默認情況下它沒有定義值( double.NaN ),因此最后得到Point,其中一個組件未定義(可能意味着什么)。 改為使用

gradRadial.GradientOrigin = new Point(pt.X / btnYes.ActualWidth, pt.Y / btnYes.ActualHeight);

至於第二個問題。 首先,樣式可以通過EventSetter設置事件處理程序。 其次,資源字典可能有代碼隱藏。 因此,您可以執行此操作。 首先將類分配給您的資源字典:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                x:Class="WpfApplication1.Resources">
</ResourceDictionary>

然后在后面定義代碼:

// this is in namespace WpfApplication1
partial class Resources : ResourceDictionary {
    public Resources() {
        InitializeComponent();
    }

    private void OnMyButtonMouseLeave(object sender, MouseEventArgs e) {
        var btn = (Button) sender;
        var gradient = btn.Background as RadialGradientBrush;
        if (gradient == null)
            return;
        gradient.GradientOrigin = new Point(0.5, 0.5); // Default
        gradient.Center = gradient.GradientOrigin;
    }

    private void OnMyButtonMouseMove(object sender, MouseEventArgs e) {
        var btn = (Button) sender;
        var gradient = btn.Background as RadialGradientBrush;
        if (gradient == null)
            return;
        Point pt = Mouse.GetPosition(btn);
        gradient.GradientOrigin = new Point(pt.X / btn.ActualWidth, pt.Y / btn.ActualHeight);
        gradient.Center = gradient.GradientOrigin;
    }
}

然后以樣式分配處理程序:

<Style TargetType="Button"
       x:Key="MyButtonStyle">
    <!-- skipped -->
    <EventSetter Event="MouseLeave" Handler="OnMyButtonMouseLeave"/>
    <EventSetter Event="MouseMove" Handler="OnMyButtonMouseMove"/>
</Style>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM