1

我在使用自定义 UniformGrid 控件时遇到问题,该控件在应用程序启动时没有缩放其所有子控件 - 我必须稍微调整窗口大小才能正确缩放内容。

UniformGrid 用作 ItemsControl 中的 ItemsPanel。ItemsControl ItemsSource 绑定到一个viewmodel 集合,UserControls 是根据viewmodel 类型选择的。这是一个片段:

<DataTemplate DataType="{x:Type indicators:RollPitchIndicatorVM}">
    <indicators:RollPitchIndicator />
</DataTemplate>

<DataTemplate DataType="{x:Type indicators:RovIllustrationIndicatorVM}">
    <indicators:RovIllustrationIndicator />
</DataTemplate>

<DataTemplate DataType="{x:Type indicators:RulerIndicatorVM}">
    <indicators:RulerIndicator />
</DataTemplate>

我的问题是用户控件的某些部分在应用程序启动时没有缩放。一个示例是 RovIllustrationIndicator 用户控件。它包含一个带有 Grid 的 Viewbox,其中包含一个 Image 控件和一个 ItemsControl 控件(我已经剥离了不相关的东西):

<Grid HorizontalAlignment="Center">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <Viewbox x:Name="RovImage" Grid.Column="1">
        <Grid>
            <Image x:Name="BackgroundImage" Source="{Binding Path=BackgroundImage}" Stretch="None" />
            <!-- ItemsControl displaying images and polygons overlaying the Image control -->
        </Grid>
    </Viewbox>
</Grid>

在应用程序启动时,Viewbox 的高度和宽度都为零。但是,如果我只调整一个像素的窗口大小,则 Viewbox 会缩放到正确的大小。

在此处输入图像描述

问题是,如果我将顶部 ItemsControl ItemsPanel 更改为标准 UniformGrid 而不是我的自定义 WeightedUniformGrid,它在启动时可以很好地扩展。因此,WeightedUniformGrid 与 UserControls 的组合导致缩放在启动时失败。但是什么?

这是 WeightedUniformGrid 实现:

public class WeightedUniformGrid : UniformGrid
{
    public static readonly DependencyProperty WeightProperty =
        DependencyProperty.RegisterAttached(
            "Weight",
            typeof(double),
            typeof(WeightedUniformGrid),
            new FrameworkPropertyMetadata(
                double.NaN,
                FrameworkPropertyMetadataOptions.AffectsParentArrange |
                FrameworkPropertyMetadataOptions.AffectsParentMeasure));

    public static double GetWeight(UIElement element)
    {
        return (double)element.GetValue(WeightProperty);
    }

    public static void SetWeight(UIElement element, double value)
    {
        element.SetValue(WeightProperty, value);
    }

    public static readonly DependencyProperty SortDirectionProperty =
        DependencyProperty.RegisterAttached(
            nameof(SortDirection),
            typeof(Orientation),
            typeof(WeightedUniformGrid),
            new FrameworkPropertyMetadata(
                Orientation.Horizontal,
                FrameworkPropertyMetadataOptions.AffectsArrange |
                FrameworkPropertyMetadataOptions.AffectsMeasure));

    public Orientation SortDirection
    {
        get { return (Orientation)GetValue(SortDirectionProperty); }
        set { SetValue(SortDirectionProperty, value); }
    }

    protected override Size MeasureOverride(Size constraint)
    {
        var size = base.MeasureOverride(constraint);
        if (Columns > 0)
        {
            double elementsPerColumn = Math.Ceiling((double)Children.Count / Columns);
            double elementWidth = size.Width / Columns;
            double unweightedElementHeight = size.Height / elementsPerColumn;
            for (int i = 0; i < Children.Count; ++i)
            {
                var child = Children[i];
                int columnNumber = (int)Math.Floor(i / elementsPerColumn);
                double weight = GetWeight(child);
                if (double.IsNaN(weight)) { weight = 100; }
                double weightedElementHeight = unweightedElementHeight * weight / 100;
                child.Measure(new Size(elementWidth, weightedElementHeight));
            }
        }
        else if (Rows > 0)
        {
            double elementsPerRow = Math.Ceiling((double)Children.Count / Rows);
            double elementHeight = size.Height / Rows;
            double unweightedElementWidth = size.Width / elementsPerRow;
            for (int i = 0; i < Children.Count; ++i)
            {
                var child = Children[i];
                int rowNumber = (int)Math.Floor(i / elementsPerRow);
                double weight = GetWeight(child);
                if (double.IsNaN(weight)) { weight = 100; }
                double weightedElementWidth = unweightedElementWidth * weight / 100;
                child.Measure(new Size(weightedElementWidth, elementHeight));
            }
        }
        return size;
    }

    protected override Size ArrangeOverride(Size arrangeSize)
    {
        var size = base.ArrangeOverride(arrangeSize);
        if (Columns > 0)
        {
            int elementsPerColumn = (int)Math.Ceiling((double)Children.Count / Columns);
            double elementWidth = size.Width / Columns;
            double unweightedElementHeight = size.Height / elementsPerColumn;
            double[] accumulatedHeightPerColumn = new double[Columns];
            for (int i = 0; i < Children.Count; ++i)
            {
                var child = Children[i];
                int columnNumber;
                if (SortDirection == Orientation.Vertical)  // Vertical orientation
                {
                    columnNumber = i / elementsPerColumn;
                }
                else  // Horizontal orientation
                {
                    columnNumber = i % Columns;
                }
                double weight = GetWeight(child);
                if (double.IsNaN(weight)) { weight = 100; }
                double weightedElementHeight = unweightedElementHeight * weight / 100;
                child.Arrange(new Rect(new Point(columnNumber * elementWidth, accumulatedHeightPerColumn[columnNumber]),
                                       new Point((columnNumber + 1) * elementWidth, accumulatedHeightPerColumn[columnNumber] + weightedElementHeight)));
                accumulatedHeightPerColumn[columnNumber] += weightedElementHeight;
            }
        }

        else if (Rows > 0)
        {
            int elementsPerRow = (int)Math.Ceiling((double)Children.Count / Rows);
            double elementHeight = size.Height / Rows;
            double unweightedElementWidth = size.Width / elementsPerRow;
            double[] accumulatedWidthPerRow = new double[Rows];
            for (int i = 0; i < Children.Count; ++i)
            {
                var child = Children[i];
                int rowNumber;
                if (SortDirection == Orientation.Vertical)  // Vertical orientation
                {
                    rowNumber = i % Rows;
                }
                else  // Horizontal orientation
                {
                    rowNumber = i / elementsPerRow;
                }
                double weight = GetWeight(child);
                if (double.IsNaN(weight)) { weight = 100; }
                double weightedElementWidth = unweightedElementWidth * weight / 100;
                child.Arrange(new Rect(new Point(accumulatedWidthPerRow[rowNumber], rowNumber * elementHeight),
                                       new Point(accumulatedWidthPerRow[rowNumber] + weightedElementWidth, (rowNumber + 1) * elementHeight)));
                accumulatedWidthPerRow[rowNumber] += weightedElementWidth;
            }
        }
        return size;
    }

}
4

0 回答 0