Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.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# 将画布调整到相邻标签的大小';s文本高度_C#_Wpf_User Controls - Fatal编程技术网

C# 将画布调整到相邻标签的大小';s文本高度

C# 将画布调整到相邻标签的大小';s文本高度,c#,wpf,user-controls,C#,Wpf,User Controls,对于WPF界面,我正在构建在标签旁边显示图标的用户控件。我在画布元素中构建图标,并将其粘贴在标签旁边的DockPanel中。我把它绑定到一个UserControl中,这样整个控件就可以绑定到一个值,重新绘制图标,并在更改时更新文本(想想电池电量表) 我无法将图标的画布缩放到与标签文本大致相同的高度,并将其大致定位在标签的基线上。有没有简单的方法可以做到这一点?如果我允许通过属性更改字体,我可以检查布局尺寸并相应地缩放/定位图标的画布吗 以下是电池电量表的XAML以及时钟和电池电量表的图像,仅供参

对于WPF界面,我正在构建在标签旁边显示图标的用户控件。我在画布元素中构建图标,并将其粘贴在标签旁边的DockPanel中。我把它绑定到一个UserControl中,这样整个控件就可以绑定到一个值,重新绘制图标,并在更改时更新文本(想想电池电量表)

我无法将图标的画布缩放到与标签文本大致相同的高度,并将其大致定位在标签的基线上。有没有简单的方法可以做到这一点?如果我允许通过属性更改字体,我可以检查布局尺寸并相应地缩放/定位图标的画布吗

以下是电池电量表的XAML以及时钟和电池电量表的图像,仅供参考。注意,电池电量表有点接近我想要的(在基线上,但不完全是文本的高度),但是时钟太大了

<UserControl x:Class="Controls.Battery"
         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:controls="clr-namespace:Controls"
         x:Name="Root"
         mc:Ignorable="d" 
         d:DesignHeight="200" d:DesignWidth="900">
<DockPanel DataContext="{Binding ElementName=Root}" LastChildFill="True" Height="200" Width="900">
    <Canvas DockPanel.Dock="Left" Width="200" Height="200" Background="Transparent">
        <Rectangle Width="180" Height="100" StrokeThickness="20" Canvas.Top="50" Stroke="White" RadiusX="5" RadiusY="5">
            <Rectangle.Fill>
                <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                    <GradientStop Color="White" Offset="0"/>
                    <GradientStop Color="White" Offset="{Binding Percent}"/>
                    <GradientStop Color="Transparent" Offset="1"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
        <Rectangle Width="40" Height="50" StrokeThickness="20" Canvas.Top="75" Canvas.Right="0" Stroke="White" RadiusX="5" RadiusY="5"/>
    </Canvas>

    <Viewbox HorizontalAlignment="Left">
        <TextBlock Text="{Binding Percent, Converter={controls:PercentConverter}}" Foreground="White" />
    </Viewbox>
</DockPanel>


您不应该在xaml中使用精确的像素值,而是应该绑定这些值并使用转换器设置正确的值。(至少我会这么做…)

因此,请命名您的文本块:

<Viewbox HorizontalAlignment="Left">
    <TextBlock x:Name="textPart" Text="{Binding Percent, Converter={controls:PercentConverter}}" Foreground="White" />
</Viewbox>
为了进一步改善外观,您应该引入转换器,它允许您将宽度设置为高度的给定百分比,或者您想要的任何东西


此外,您还可以在画布中引入一个,这很可能会减少对转换器的需求,因为您可以设计一个大小的“图片”,并且只修改scaleTransform使其大小合适。

这是我能找到的最接近解决方案。我将TextBlock移动到画布内,并用一个ViewBox包装以缩放整个地块,并在TextBlock周围使用一个ViewBox来缩放以匹配画布高度。我还将画布高度更改为100(以消除电池上方和下方的空间),并对矩形进行了一些定位调整:-

        <Viewbox Stretch="Uniform"
                 StretchDirection="Both">
            <Canvas DockPanel.Dock="Left"
                    Width="400"
                    Height="100"
                    Background="Black">
                <Rectangle Width="180"
                           Height="100"
                           StrokeThickness="20"
                           Canvas.Top="0"
                           Stroke="White"
                           RadiusX="5"
                           RadiusY="5">
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint="0,0"
                                             EndPoint="1,0">
                            <GradientStop Color="White"
                                          Offset="0" />
                            <GradientStop Color="White"
                                          Offset="{Binding Percent}" />
                            <GradientStop Color="Transparent"
                                          Offset="1" />
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
                <Rectangle Width="40"
                           Height="50"
                           StrokeThickness="20"
                           Canvas.Top="25"
                           Canvas.Right="200"
                           Stroke="White"
                           RadiusX="5"
                           RadiusY="5" />

                <Viewbox Stretch="UniformToFill"
                         StretchDirection="Both"
                         Canvas.Left="200"
                         Height="100">
                    <TextBlock Text="1%"
                               Padding="0"
                               Margin="0"
                               LineStackingStrategy="BlockLineHeight"
                               LineHeight="20"
                               FontSize="20"
                               Foreground="White" />
                </Viewbox>
            </Canvas>
        </Viewbox>

把它放到一个窗口中——你会发现画布和文本在调整窗口大小时都会按比例缩放(并保持它们的纵横比)

电池没有完全与文本的顶部和底部对齐,但我怀疑这是因为字体本身存在间距。我发现我可以通过在
文本块
上使用负的上下边距来改善情况,但这可能是“黑客行为”,因为调整量取决于所使用的字体


可能有更优雅的解决方案,例如,使用电池图标的几何图形/路径。顺便说一句,你有没有看过优秀的“Metro Studio”工具?这是一个免费的XAML图标集合-里面有一些电池,您可以根据自己的需要调整电池。

画布的子元素永远不会调整大小,它们只是定位在指定的坐标处。因此,更改画布的大小不会影响其子对象。此外,画布的子元素始终具有它们所需的完整大小。所以在你的例子中,我认为最好使用网格元素。 诸如此类:

<UserControl x:Class="Controls.Battery"
     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:controls="clr-namespace:Controls"
     x:Name="Root"
     mc:Ignorable="d" 
     d:DesignHeight="200" d:DesignWidth="900">
<Grid DataContext="{Binding ElementName=Root}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Viewbox Grid.Column="0"
             VerticalAlignment="Center"
             Stretch="Uniform"
             StretchDirection="Both">
        <Grid Margin="10 60 10 40">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Rectangle Grid.Column="0"
                       Width="180"
                       Height="100"
                       RadiusX="5"
                       RadiusY="5"
                       Stroke="White"
                       StrokeThickness="20">
                <Rectangle.Fill>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                        <GradientStop Offset="0" Color="White" />
                        <GradientStop Offset="{Binding Percent}" Color="White" />
                        <GradientStop Offset="1" Color="Transparent" />
                    </LinearGradientBrush>
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Grid.Column="1"
                       Width="40"
                       Height="50"
                       Margin="-20 0 0 0"
                       RadiusX="5"
                       RadiusY="5"
                       Stroke="White"
                       StrokeThickness="20" />
        </Grid>
    </Viewbox>

    <Viewbox Grid.Column="1"
             HorizontalAlignment="Left"
             VerticalAlignment="Center">
        <TextBlock Foreground="White" Text="{Binding Percent, Converter={controls:PercentConverter}}" />
    </Viewbox>
</Grid>


感谢您的精彩回答,以及您为此付出的所有努力。我对此表示赞赏,但还是采用了基于公认答案的方法+从我这里得到1。
<UserControl x:Class="Controls.Battery"
     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:controls="clr-namespace:Controls"
     x:Name="Root"
     mc:Ignorable="d" 
     d:DesignHeight="200" d:DesignWidth="900">
<Grid DataContext="{Binding ElementName=Root}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Viewbox Grid.Column="0"
             VerticalAlignment="Center"
             Stretch="Uniform"
             StretchDirection="Both">
        <Grid Margin="10 60 10 40">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Rectangle Grid.Column="0"
                       Width="180"
                       Height="100"
                       RadiusX="5"
                       RadiusY="5"
                       Stroke="White"
                       StrokeThickness="20">
                <Rectangle.Fill>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                        <GradientStop Offset="0" Color="White" />
                        <GradientStop Offset="{Binding Percent}" Color="White" />
                        <GradientStop Offset="1" Color="Transparent" />
                    </LinearGradientBrush>
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Grid.Column="1"
                       Width="40"
                       Height="50"
                       Margin="-20 0 0 0"
                       RadiusX="5"
                       RadiusY="5"
                       Stroke="White"
                       StrokeThickness="20" />
        </Grid>
    </Viewbox>

    <Viewbox Grid.Column="1"
             HorizontalAlignment="Left"
             VerticalAlignment="Center">
        <TextBlock Foreground="White" Text="{Binding Percent, Converter={controls:PercentConverter}}" />
    </Viewbox>
</Grid>