如何在WPF中对非透明用户控件进行透明部分

时间:2017-12-13 09:20:51

标签: wpf xaml transparency

在我的MainWindow.xaml上有用户控件图块,每个图块的背景设置如下:

ucTile.Background = new SolidColorBrush(Colors.Some);

取决于各种用户设置。

现在我想为我的应用添加一项新功能:为主窗口设置自定义背景图片的可能性

但是我需要将我的瓷砖的某些部分透明,以显示它们下面的图像。像这样:

window example

这就是我的瓷砖现在的样子:

tiles

如何实现?我不能将我的ucTile背景设置为透明,因为如果应该保持着色。 是否可能有一些组件inf WPF会充当“漏洞”,显示非透明元素下的内容?

2 个答案:

答案 0 :(得分:1)

简单的解决方案:

<Window Background="Transparent">
    <Polygon Fill="LightBlue"/>
</Window>

您需要添加Points才能获得所需的形状!

详细了解Polygon here!

这里有一些细节,因为有些人感觉像是贬低,因为没有明显的理由是好的......

<强>用户控件

<UserControl x:Class="WpfApp1.FolderControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WpfApp1"
         mc:Ignorable="d">
<Grid Margin="10">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Polygon Fill="Red"
             Grid.RowSpan="2"
             Points="0,0 , 50,0 , 55,10 , 100,10 , 100,80 , 0,80 " />
    <Image Source="if_desktop_83651.png" Margin="5,20,5,5" Height="24" Width="24"></Image>
    <Border Background="Green"
            Grid.Row="1"
            Margin="5">
        <TextBlock Text="Caption" 
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"
                   Foreground="White"/>
    </Border>
</Grid>

<强>窗口

<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525"
    Background="Green">
<local:FolderControl HorizontalAlignment="Center"
                     VerticalAlignment="Center"/>

<强>结果

enter image description here

<强>优点:

  • 你可以做任何你想要的形状

<强>缺点:

  • 赢取&#tt调整大小 - &gt;在代码
  • 中计算Points

答案 1 :(得分:0)

您可以在ControlTemplate中为UserControl的大纲设置Path元素。路径的FillStrokeStrokeThickness属性绑定到UserControl&#39; BackgroundBorderBrush和(新定义的){ {1}},因此您可以照常设置它们。

OutlineThickness

Path绑定到Tile控件的两个依赖属性:

<UserControl x:Class="YourNamespace.Tile" ...>
    <UserControl.Template>
        <ControlTemplate TargetType="local:Tile">
            <Grid>
                <Path Fill="{TemplateBinding Background}"
                      Stroke="{TemplateBinding BorderBrush}"
                      StrokeLineJoin="Round"
                      StrokeThickness="{TemplateBinding OutlineThickness}"
                      Data="{TemplateBinding Outline}"/>

                <ContentPresenter
                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </Grid>
        </ControlTemplate>
    </UserControl.Template>
    <Grid>
        ...
    </Grid>
</UserControl>

现在根据需要扩展public partial class Tile : UserControl { public Tile() { InitializeComponent(); } public static readonly DependencyProperty OutlineProperty = DependencyProperty.Register( nameof(Outline), typeof(Geometry), typeof(Tile)); public Geometry Outline { get { return (Geometry)GetValue(OutlineProperty); } set { SetValue(OutlineProperty, value); } } public static readonly DependencyProperty OutlineThicknessProperty = DependencyProperty.Register( nameof(OutlineThickness), typeof(double), typeof(Tile), new PropertyMetadata(1.0, (o, e) => ((Tile)o).UpdateOutline())); public double OutlineThickness { get { return (double)GetValue(OutlineThicknessProperty); } set { SetValue(OutlineThicknessProperty, value); } } protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { base.OnRenderSizeChanged(sizeInfo); UpdateOutline(); } private void UpdateOutline() { var geometry = new StreamGeometry(); var size = RenderSize; var border = OutlineThickness / 2d; using (var sgc = geometry.Open()) { sgc.BeginFigure(new Point(border, border), true, true); sgc.LineTo(new Point(size.Width - 20, border), true, true); sgc.LineTo(new Point(size.Width - border, 20), true, true); sgc.LineTo(new Point(size.Width - border, size.Height - border), true, true); sgc.LineTo(new Point(0, size.Height - border), true, true); } Outline = geometry; } } 方法。

如果XAML设计者抱怨ControlTemplate的TargetType,你也可以使用它:

UpdateOutline