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