Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF:鼠标在控件上移动时的径向渐变_C#_Wpf_Xaml_Visual Studio 2008_Gradient - Fatal编程技术网

C# WPF:鼠标在控件上移动时的径向渐变

C# WPF:鼠标在控件上移动时的径向渐变,c#,wpf,xaml,visual-studio-2008,gradient,C#,Wpf,Xaml,Visual Studio 2008,Gradient,我想在鼠标移动到按钮上时对其应用径向渐变效果,如前所述。因此,我有一个单独的资源文件,在其中定义我的按钮样式 MyButtonStyle.xaml: <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

我想在鼠标移动到按钮上时对其应用径向渐变效果,如前所述。因此,我有一个单独的资源文件,在其中定义我的按钮样式

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;
    }
我的问题和目标是:

  • 未正确应用径向渐变。我的意思是,径向梯度显示在我的按钮的中心,而不将鼠标放在上面,当鼠标在按钮上移动时,径向梯度始终保持在中心,径向梯度不是从我的鼠标在上面的原点生成的,如图中所示的三个鼠标的屏幕截图
  • 使用代码隐藏迫使我为每个按钮创建两个事件,MouseMove和MouseLeave。我想不用代码,只使用xaml,将所有代码放在一个文件中,就放在我的样式文件MyButtonStyle.xaml中

  • 出现第一个问题的原因是:

    gradRadial.GradientOrigin = new Point(pt.X / btnYes.Width, pt.Y / btnYes.Height);
    
    您使用的是
    btnYes.Width
    ,但您没有为按钮设置此属性,并且默认情况下它没有定义值(
    double.NaN
    ),因此最终导致一个组件未定义(无论这意味着什么)。改用

    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>
    
    然后以样式分配处理程序:

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

    第一个问题的发生是因为:

    gradRadial.GradientOrigin = new Point(pt.X / btnYes.Width, pt.Y / btnYes.Height);
    
    您使用的是
    btnYes.Width
    ,但您没有为按钮设置此属性,并且默认情况下它没有定义值(
    double.NaN
    ),因此最终导致一个组件未定义(无论这意味着什么)。改用

    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>
    
    然后以样式分配处理程序:

    <Style TargetType="Button"
           x:Key="MyButtonStyle">
        <!-- skipped -->
        <EventSetter Event="MouseLeave" Handler="OnMyButtonMouseLeave"/>
        <EventSetter Event="MouseMove" Handler="OnMyButtonMouseMove"/>
    </Style>
    
    
    
    我想问题1的答案可以在您提供的链接中找到。注意这一重要细节
    我们还需要在鼠标悬停在按钮上时禁用按钮的默认渲染。我们可以通过将ButtonChrome对象的RenderMouseOver属性(位于按钮的控件模板中)更改为False来完成此操作。
    @pstrjds ok我已经完成了。现在,在我的样式文件中,当鼠标位于按钮上方时,如何禁用按钮的默认渲染?我想问题1的答案可以在您提供的链接中找到。注意这一重要细节
    我们还需要在鼠标悬停在按钮上时禁用按钮的默认渲染。我们可以通过将ButtonChrome对象的RenderMouseOver属性(位于按钮的控件模板中)更改为False来完成此操作。
    @pstrjds ok我已经完成了。现在,在我的样式文件中,当鼠标位于按钮上方时,我如何禁用按钮的默认呈现?嗯,向OP指出,如果他们只是调试
    MouseMove
    处理程序并检查
    点的值,他们会立即将
    X
    值视为
    NaN
    ,这将非常有用,这应该会使他们返回到
    宽度
    值,该值也是
    NaN
    (即默认值)。@PeterDuniho这是真的,尽管我有点惊讶,这并不会导致道路沿线的某个地方出现异常(在点构造函数中,或将无效点指定给GradientOrigin时)。虽然在坐标未定义的情况下,这一点可能有某种意义,但我就是看不出来。@PeterDuniho,你是对的。但由于没有抛出任何异常,我认为值是可以的。下次我会小心的。@Evk它没有抛出任何异常,所以让我很困惑。你的解决方案很有魅力!我已把你的答案标为正确。Thx人!因此,有必要向OP指出,如果他们只是调试
    MouseMove
    处理程序并检查
    点的值,他们会立即看到
    X
    值为
    NaN
    ,这应该会使他们回到
    宽度
    值也是
    NaN
    (即默认值)。@PeterDuniho这是真的,尽管我有点惊讶,这不会导致道路上的某个地方出现异常(在点构造函数中,或在为GradientOrigin指定无效点时)。虽然在未定义坐标的点上可能有某种意义,但我就是看不到。@PeterDuniho你是对的。但由于它没有引发任何异常,我认为值是可以的。下次我会小心。@Evk它没有引发任何异常,所以它让我困惑。你的解决方案非常有效!我已将你的答案标记为a这是正确的。谢谢!