【问题标题】:Background drawing with inner offset带内偏移的背景图
【发布时间】:2019-10-04 10:01:53
【问题描述】:

我希望我的 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 从“Fill”替换为“None”,我的 UserControl 中间会出现一个黑点。

【问题讨论】:

  • 偏移应该有什么背景?你不能在消费视图中设置UserControlMargin 吗? &lt;local:Readout Margin="10" /&gt;

标签: wpf


【解决方案1】:

如果没有精确描述您希望控件的行为方式,就不可能提供关于您的代码应该是什么样子的精确细节。

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

但是,根据我的经验,viewbox/viewport 方法总是有点“繁琐”。或者更确切地说,很难直观地掌握这些参数的作用,因此人们经常只是摆弄这些值,直到它们得到他们想要的结果,结果是实现不是很好的泛化或可重用。

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

例如:

<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>

这正是这样做的。 IE。所有内容,包括它拥有的任何背景,都将在用户控件中插入 5 个像素。它看起来像这样:

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

另一方面,也许您希望内容完全填充控件,但只有背景插图。虽然(正如我提到的)你可以摆弄背景画笔的视框和视口来完全控制背景的渲染,理论上这甚至可能是“最好”或“最正确”的方式,在大多数情况下它不应该是必要的。相反,只需提供单独的元素来提供背景并显示在控件的其余内容下方。

<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>

看起来像这样:

虽然上面的示例使用&lt;ContentControl/&gt; 元素来包含用户控件的实际内容,但这并不是绝对必要的。这只是一种方便的方式来表示“这里是你所有内容的去向”。但当然,任何类型的内容都可以放在这里,只要它是 &lt;Grid/&gt; 的有效子代。这里的关键是它与作为背景的插入 &lt;Rectangle/&gt; 元素共享网格单元,因此呈现为覆盖在该背景之上。

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

<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>

【讨论】:

    猜你喜欢
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    相关资源
    最近更新 更多