内部偏移的背景图

时间:2019-10-04 10:01:53

标签: wpf

我希望我的UserControl具有黑色背景。小事情是我希望它的侧面有些偏移。

我是这样做的:

<UserControl x:Class="PitramVisionPlayerUI.Controls.Readout"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="50" d:DesignWidth="200">
    <UserControl.Background>
        <DrawingBrush Stretch="Fill">
            <DrawingBrush.Drawing>
                <GeometryDrawing>
                    <GeometryDrawing.Geometry>
                        <PathGeometry>
                            <PathFigure IsClosed="True" StartPoint="0.1,0.1">
                                <PathFigure.Segments>
                                    <LineSegment Point="0.9,0.1" />
                                    <LineSegment Point="0.9,0.9" />
                                    <LineSegment Point="0.1,0.9" />
                                </PathFigure.Segments>
                            </PathFigure>
                        </PathGeometry>
                    </GeometryDrawing.Geometry>
                    <GeometryDrawing.Brush>
                        <SolidColorBrush Color="Black"></SolidColorBrush>
                    </GeometryDrawing.Brush>
                </GeometryDrawing>
            </DrawingBrush.Drawing>
        </DrawingBrush>
    </UserControl.Background>
</UserControl>

问题是它不起作用。它不断填充整个矩形。如果我将DrawingBrush的属性Stretch从“填充”替换为“无”,我的UserControl中间会出现一个黑点。

1 个答案:

答案 0 :(得分:0)

没有精确描述控件的行为方式,就无法提供有关代码外观的精确细节。

通常,对于DrawingBrush(或任何TileBrush),您可以使用ViewboxViewport属性来修改基本内容画笔的渲染。例如,通过提供一个比实际内容大一点的视图框,可以缩小视口(即输出区域)内的整体渲染。

但是,根据我的经验,viewbox / viewport方法总是有点“麻烦”。或者更确切地说,很难很好地直观了解这些参数的作用,因此,人们常常只需要摆弄这些值,直到获得所需的结果为止,结果是该实现的推广性或可重用性不是很好。

根据您的问题,目前尚不清楚您需要在此插入黑色背景与控件中其余内容之间建立什么样的关系。但是,一种非常简单的方法就是简单地设置Padding本身的UserControl属性,从而使控件内的所有内容被给定的填充量插入。

例如:

<UserControl x:Class="TestSO58234176BackgroundBorder.UserControl1"
             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:l="clr-namespace:TestSO58234176BackgroundBorder"
         <!-- Padding set to 5 pixels, so content (including background) is inset -->
             Padding="5" mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
  <Grid Background="Black">
    <!-- Stretch the text so it's clear what the extent of the content is -->
    <Viewbox Stretch="Fill">
      <TextBlock Text="This is a test" Foreground="LightGreen" FontWeight="Bold"/>
    </Viewbox>
  </Grid>
</UserControl>

这将完全做到这一点。即所有内容,包括其具有的背景,都将在用户控件中插入5个像素。看起来像这样: enter image description here

(红色边框位于用户控件周围的窗口标记中,因此更容易查看用户控件本身的实际尺寸。)

另一方面,也许您希望内容完全填充控件,但仅具有背景插图。尽管(如我所述),您可以摆弄背景笔刷的视区和视口以完全控制背景的渲染,但从理论上讲,在大多数情况下,这甚至可能是“最佳”或“最正确”的方式它没有必要。取而代之的是,只需提供单独的元素来提供背景,并显示在控件的其余内容下。

<UserControl x:Class="TestSO58234176BackgroundBorder.UserControl1"
             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:l="clr-namespace:TestSO58234176BackgroundBorder"
             d:DesignHeight="450" d:DesignWidth="800">
  <Grid>
<!-- Put a black rectangle under the actual content of the control, to act as an inset background -->
    <Rectangle Fill="Black" Margin="5"/>
<!-- Put the actual content of the control inside this <ContentControl/> element -->
    <ContentControl>
      <Viewbox Stretch="Fill">
        <TextBlock Text="This is a test" Foreground="LightGreen" FontWeight="Bold"/>
      </Viewbox>
    </ContentControl>
  </Grid>
</UserControl>

如下所示: enter image description here

尽管上面的示例使用<ContentControl/>元素来包含用户控件的实际内容,但这并不是绝对必要的。这只是表示“所有内容都在这里”的一种便捷方式。但是,当然,任何内容都可以在此处使用,只要它是<Grid/>的有效子元素即可。这里的关键是它与充当背景的插入<Rectangle/>元素共享网格单元,并因此渲染为覆盖在该背景之上。

如果愿意,您甚至可以概括上述内容,以使“背景”矩形成为用户控件模板的一部分,而不是直接内容。这样,用户控件的视觉方面本身与用户控件的实际内容之间有明显的区别:

<UserControl x:Class="TestSO58234176BackgroundBorder.UserControl1"
             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:l="clr-namespace:TestSO58234176BackgroundBorder"
             mc:Ignorable="d" 
             Padding="5"
             d:DesignHeight="450" d:DesignWidth="800">
  <UserControl.Template>
    <ControlTemplate TargetType="{x:Type l:UserControl1}">
      <Grid>
        <Rectangle Fill="Black" Margin="5"/>
        <ContentPresenter/>
      </Grid>
    </ControlTemplate>
  </UserControl.Template>
  <Viewbox Stretch="Fill">
    <TextBlock Text="This is a test" Foreground="LightGreen" FontWeight="Bold"/>
  </Viewbox>
</UserControl>