WPF:Canvas中的TextBlock

时间:2015-11-02 00:17:23

标签: c# wpf canvas

我正在尝试将TextBlock放在我的Canvas中,但它似乎没有按预期工作。我希望当添加更多文本时,中心点会明显改变,因此它保持居中。

这是正在制作的内容,3个图像显示有1个数字,2个数字和3个。

enter image description here

这是我的ControlTemplate

<Style TargetType="ProgressBar" x:Key="CircularProgress">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ProgressBar">
                    <Grid x:Name="PathGrid" Margin="2" Width="200">
                        <Canvas>
                            <TextBlock x:Name="PathPercentage" Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Value, StringFormat={}{0}%}"
                                    Foreground="White"
                                    FontFamily="DefaultFont"
                                    FontSize="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource SizeTextOnParent}}">
                                <TextBlock.Margin>
                                    <MultiBinding Converter="{StaticResource CenterElement}">
                                        <Binding ElementName="PathGrid" Path="ActualWidth"/>
                                        <Binding ElementName="PathPercentage" Path="FontSize" />
                                        <Binding ElementName="PathPercentage" Path="FontFamily"/>
                                        <Binding ElementName="PathPercentage" Path="Text"/>
                                    </MultiBinding>
                                </TextBlock.Margin>
                            </TextBlock>
                            <TextBlock Text="{Binding ElementName=PathPercentage, Path=Margin}" />
                            <Ellipse Fill="Transparent" 
                                 Stroke="#434953" 
                                 StrokeThickness="3" 
                                 Width="{Binding ElementName=PathGrid, Path=ActualWidth}" 
                                 Height="{Binding ElementName=PathGrid, Path=ActualWidth}" />

                            <Path x:Name="pathRoot" 
                              Stroke="#8ab71c" 
                              StrokeThickness="6" 
                              HorizontalAlignment="Center" 
                              VerticalAlignment="Top">

                                <Path.Data>
                                    <PathGeometry>
                                        <PathFigureCollection>
                                            <PathFigure StartPoint="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource StartPointConverter}, Mode=OneWay}">
                                                <ArcSegment Size="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource ArcSizeConverter}, Mode=OneWay}" SweepDirection="Clockwise">
                                                    <ArcSegment.IsLargeArc>
                                                        <MultiBinding Converter="{StaticResource LargeArcConverter}">
                                                            <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" />
                                                            <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" />
                                                            <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" />
                                                            <Binding ElementName="FullyIndeterminateGridScaleTransform" Path="ScaleX" />
                                                        </MultiBinding>
                                                    </ArcSegment.IsLargeArc>
                                                    <ArcSegment.Point>
                                                        <MultiBinding Converter="{StaticResource ArcEndPointConverter}">
                                                            <Binding ElementName="PathGrid" Path="ActualWidth" />
                                                            <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" />
                                                            <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" />
                                                            <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" />
                                                            <Binding ElementName="FullyIndeterminateGridScaleTransform" Path="ScaleX" />
                                                        </MultiBinding>
                                                    </ArcSegment.Point>
                                                </ArcSegment>
                                            </PathFigure>
                                        </PathFigureCollection>
                                    </PathGeometry>
                                </Path.Data>
                            </Path>
                        </Canvas>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

这是定义TextBlocks边距的 CenterElement 转换器

namespace Test_Project.Converters
{
    public class CenterElement : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            double parentWidth = (double)values[0];
            double fontSize = (double)values[1];
            FontFamily fontFamily = (FontFamily)values[2];
            string text = (string)values[3];

            var textBlock = new TextBlock {
                Text = text,
                TextWrapping = TextWrapping.Wrap,
                FontFamily = fontFamily,
                FontSize = fontSize};

            textBlock.Measure(new Size());
            textBlock.Arrange(new Rect());

            Console.WriteLine("Height: " + textBlock.ActualHeight + " Width: " + textBlock.ActualWidth + " Text: " + text);

            double h = Math.Round(((parentWidth / 2) - (textBlock.ActualHeight / 2)),2);
            double w = Math.Round(((parentWidth / 2) - (textBlock.ActualWidth / 2)), 2);

            Thickness margin = new Thickness(w,h,0,0);

            return margin;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我只是将文本框的宽度绑定到整个画布的ActualWidth,并将TextAlignment设置为&#34; Center&#34;:

<TextBlock Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=Canvas}}" TextAlignment="Center" ...etc... />

如果你不想要它在画布的确切中心,那么你总是可以用Margin来抵消它。