Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.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_Binding_Styling_Shadow - Fatal编程技术网

C# 更改类绑定阴影颜色WPF

C# 更改类绑定阴影颜色WPF,c#,wpf,binding,styling,shadow,C#,Wpf,Binding,Styling,Shadow,我正在研究如何在WPF文档中复制Google按钮的悬停阴影效果,结果发现:,这正好回答了我的问题,但我唯一的问题是我通常用XAML做所有前端工作,因此我对C#的样式设计不是很有经验。我的问题是,我想“绑定”我的前景色和阴影色,这是因为在代码中它只将其设置为灰色,这意味着我必须为我想要设置的每种颜色执行一个完整的其他类。这是我现在的代码: MainWindow.xaml: <Button Content="shadow"> <Button.Style>

我正在研究如何在WPF文档中复制Google按钮的悬停阴影效果,结果发现:,这正好回答了我的问题,但我唯一的问题是我通常用XAML做所有前端工作,因此我对C#的样式设计不是很有经验。我的问题是,我想“绑定”我的前景色和阴影色,这是因为在代码中它只将其设置为灰色,这意味着我必须为我想要设置的每种颜色执行一个完整的其他类。这是我现在的代码:

MainWindow.xaml:

<Button Content="shadow">
        <Button.Style>
            <Style TargetType="Button">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="local:UI.Elevation" Value="10"/>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="False">
                        <Setter Property="local:UI.Elevation" Value="0"/>

                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
</Button>

用户界面:

public static class UI
{

    public static readonly DependencyProperty ElevationProperty = DependencyProperty.RegisterAttached("Elevation", typeof(double), typeof(UI), new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsRender, null, OnRedElevationChanged));

    public static double GetElevation(this UIElement element) => element.GetValue(ElevationProperty) as double? ?? default;

    public static void SetElevation(this UIElement element, double elevation) => element.SetValue(ElevationProperty, elevation);

    private static object OnRedElevationChanged(DependencyObject d, object value)
    {
        if (d is UIElement element && value is double elevation)
            if (elevation == 0)
                element.Effect = null;
            else
            {
                Effect e = CreateElevation(elevation, element.Effect);
                if (e != null)
                    element.Effect = e;
            }
        return value;
    }

    private static Effect CreateElevation(double elevation, Effect source)
    {
        void MixShadows(DropShadowEffect nearest, DropShadowEffect matched, double balance)
        {
            matched.BlurRadius = matched.BlurRadius * (1 - balance) + nearest.BlurRadius * balance;
            matched.ShadowDepth = matched.ShadowDepth * (1 - balance) + nearest.ShadowDepth * balance;
        }
        DropShadowEffect[] shadows = new DropShadowEffect[]
        {
        new DropShadowEffect()
        {
            BlurRadius = 5,
            ShadowDepth = 1
        },
        new DropShadowEffect()
        {
            BlurRadius = 8,
            ShadowDepth = 1.5
        },
        new DropShadowEffect()
        {
            BlurRadius = 14,
            ShadowDepth = 4.5
        },
        new DropShadowEffect()
        {
            BlurRadius = 25,
            ShadowDepth = 8
        },
        new DropShadowEffect()
        {
            BlurRadius = 35,
            ShadowDepth = 13
        }
        };
        elevation = Math.Max(0, elevation / 12 * shadows.Length - 1);
        int prevIndex = (int)Math.Floor(elevation), index = (int)elevation, nextIndex = (int)Math.Ceiling(elevation);
        double approx = elevation - index;
        DropShadowEffect shadow = shadows[index];
        if (approx != 0)
            MixShadows(approx < 0 ? shadows[prevIndex] : shadows[nextIndex], shadow, Math.Abs(approx));
        bool modify = false;
        if (source is DropShadowEffect sourceShadow)
        {
            sourceShadow.BlurRadius = shadow.BlurRadius;
            sourceShadow.ShadowDepth = shadow.ShadowDepth;
            shadow = sourceShadow;
            modify = true;
        }
        shadow.Direction = 270;
        shadow.Color = Colors.Red;
        shadow.Opacity = .42;
        shadow.RenderingBias = RenderingBias.Performance;
        return modify ? null : shadow;
    }
}
公共静态类UI
{
public static readonly dependencProperty ElevationProperty=dependencProperty.RegisterAttached(“高程”、typeof(双精度)、typeof(UI)、new FrameworkPropertyMetadata(默认值(双精度)、FrameworkPropertyMetadata.AffectsRender、null、OnRedeElevationChanged));
公共静态双GetElevation(此UIElement元素)=>element.GetValue(ElevationProperty)作为双???默认值;
公共静态void SetElevation(此UIElement元素,双立面)=>element.SetValue(ElevationProperty,立面);
私有静态对象OnRedElevationChanged(DependencyObject d,对象值)
{
如果(d为UIElement,元素值为双立面(&V))
如果(高程==0)
element.Effect=null;
其他的
{
效果e=CreateElevation(标高,元素效果);
如果(e!=null)
元素效应=e;
}
返回值;
}
专用静态效果CreateElevation(双立面,效果源)
{
void MixShadows(最近的DropShadowEffect,匹配的DropShadowEffect,双平衡)
{
matched.BlurRadius=matched.BlurRadius*(1-平衡)+最近的.BlurRadius*平衡;
matched.ShadowDepth=matched.ShadowDepth*(1-平衡)+最近的.ShadowDepth*平衡;
}
DropShadowEffect[]阴影=新的DropShadowEffect[]
{
新的DropShadowEffect()
{
半径=5,
阴影深度=1
},
新的DropShadowEffect()
{
半径=8,
阴影深度=1.5
},
新的DropShadowEffect()
{
半径=14,
阴影深度=4.5
},
新的DropShadowEffect()
{
半径=25,
阴影深度=8
},
新的DropShadowEffect()
{
半径=35,
阴影深度=13
}
};
标高=数学最大值(0,标高/12*阴影。长度-1);
int prevIndex=(int)数学地板(标高),index=(int)标高,nextIndex=(int)数学天花板(标高);
双近似值=高程-指数;
DropShadowEffect阴影=阴影[索引];
如果(大约!=0)
混合阴影(大约<0?阴影[prevIndex]:阴影[nextIndex]、阴影、数学Abs(大约));
bool-modify=false;
if(源为DropShadowEffect sourceShadow)
{
sourceShadow.BlurRadius=shadow.BlurRadius;
sourceShadow.ShadowDepth=shadow.ShadowDepth;
shadow=sourceShadow;
修改=真;
}
阴影方向=270;
shadow.Color=Colors.Red;
阴影.不透明度=.42;
shadow.RenderingBias=RenderingBias.Performance;
返回修改?空:阴影;
}
}
为了在XAML中得到我想要的东西,我会这样做:

<Button Content="shadow">
        <Button.Style>
            <Style TargetType="Button">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="local:UI.Elevation" Value="10"/>
                        <Setter Property="local:UI.Elevation.Foreground" Value="Blue"/>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="False">
                        <Setter Property="local:UI.Elevation" Value="0"/>
                        <Setter Property="local:UI.Elevation.Foreground" Value="Blue"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
</Button>


但是我不太知道如何连接
local:UI.Elevation.Foreground
要更改阴影颜色,我必须从
UI.cs
更改这一行:
shadow.Color=Colors.Red并将其绑定到立面。前景,但我遇到了困难。有人能帮忙吗?

您只需使用名为
Color
Color
类型的新附加属性更新UI类,并为其指定您喜欢的默认颜色

然后,在其
OnColorChanged
处理程序中,调用
OnElevationChanged
,以便重新创建阴影

#region Color (Attached Property)
public static readonly DependencyProperty ColorProperty =
    DependencyProperty.RegisterAttached(
        "Color",
        typeof(Color),
        typeof(UI),
        new PropertyMetadata(Colors.Black, OnColorChanged));

public static Color GetColor(DependencyObject obj)
{
    return (Color)obj.GetValue(ColorProperty);
}

public static void SetColor(DependencyObject obj, Color value)
{
    obj.SetValue(ColorProperty, value);
}

private static void OnColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    OnElevationChanged(d, GetElevation((UIElement)d));
}
#endregion
CreateElevation
方法中,为颜色添加一个新参数,以便进行设置

private static Effect CreateElevation(double elevation, Effect source, Color color)
{
    ...
    shadow.Color = color;
    ...
}
最后,在
OnElevationChanged
中更新它,以便调用
GetColor
,以便它可以传入新的
Color
属性

private static object OnElevationChanged(DependencyObject d, object value)
{
    if (d is UIElement element && value is double elevation)
        if (elevation == 0)
            element.Effect = null;
        else
        {
            Effect e = CreateElevation(elevation, element.Effect, GetColor(element));
            if (e != null)
                element.Effect = e;
        }
    return value;
}
示例XAML

<Button
    Width="100"
    Height="20"
    Content="shadow">
    <Button.Style>
        <Style TargetType="Button">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="local:UI.Elevation" Value="10" />
                    <Setter Property="local:UI.Color" Value="Blue" />
                </Trigger>
                <Trigger Property="IsMouseOver" Value="False">
                    <Setter Property="local:UI.Elevation" Value="5" />
                    <Setter Property="local:UI.Color" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>


注意:您可以进行一些重构,以使所有这些更干净,但希望这能让您开始。

因此,我制作了一个
DependencyProperty colorProperty
和一个
OnColourChanged
事件,但我不明白如何将其发送到
OnElevationChanged
,在那里我可以把它发送到
CreateElevation
我用工作代码更新了我的答案。您可能应该投入一些时间来了解附加属性是如何工作的。这将帮助您更好地理解代码。通过附加的属性/行为,您可以做很多事情!:)工程伟大和预期!一定要研究附加属性和使用C#的更多前端设计。再次感谢!