在wpf网格中缩放线条

时间:2015-03-23 14:35:59

标签: c# wpf

我有用户控制权:

<UserControl x:Class="WpfExt.ColorLine.TimeLineControl"
             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="40" d:DesignWidth="400">
    <Grid x:Name="DynamicGrid">

    </Grid>
</UserControl>

在代码背后:

public readonly static DependencyProperty TotalHoursProperty = DependencyProperty.Register("TotalHours",
            typeof(int),
            typeof(TimeLineControl),
            new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.AffectsParentMeasure, TotalHoursChangedCallback));


        private static void TotalHoursChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            ((TimeLineControl)dependencyObject).ChangeTimeLineItems((int)e.NewValue);
        }

        public int TotalHours
        {
            get { return (int)GetValue(TotalHoursProperty); }
            set { SetValue(TotalHoursProperty, value); }
        }

        private void ChangeTimeLineItems(int totalHours)
        {
            if (totalHours < 1 || totalHours > 24) throw new InvalidOperationException("TotalHours should be in 1..24 range.");

            DynamicGrid.Children.Clear();

            AddExtremeLine(0, HorizontalAlignment.Left);

            for (var index = 1; index < totalHours * 2 - 1; index += 2)
            {
                AddLine(index, 30);
                AddLine(index + 1, 40);
            }
            AddLine(totalHours * 2 - 1, 30);

            AddExtremeLine(totalHours * 2, HorizontalAlignment.Right);
        }

        private void AddExtremeLine(int column, HorizontalAlignment horizontalAlignment)
        {
            var columnDefinition = new ColumnDefinition();
            var gridLength = new GridLength(0.5, GridUnitType.Star);
            columnDefinition.Width = gridLength;

            DynamicGrid.ColumnDefinitions.Add(columnDefinition);

            var line = new Line
            {
                X1 = 0,
                X2 = 0,
                Y1 = 20,
                Y2 = 40,
                Stroke = Brushes.Black,
                StrokeThickness = 1,
                HorizontalAlignment = horizontalAlignment
            };
            Grid.SetColumn(line, column);

            DynamicGrid.Children.Add(line);
        }

        private void AddLine(int column, double y2)
        {
            var columnDefinition = new ColumnDefinition();
            var gridLength = new GridLength(1, GridUnitType.Star);
            columnDefinition.Width = gridLength;

            DynamicGrid.ColumnDefinitions.Add(columnDefinition);

            var line = new Line
            {
                X1 = 0,
                X2 = 0,
                Y1 = 20,
                Y2 = y2,
                Stroke = Brushes.Black,
                StrokeThickness = 1,
                HorizontalAlignment = HorizontalAlignment.Center
            };
            Grid.SetColumn(line, column);

            DynamicGrid.Children.Add(line);
        }

所以,如果我使用它:

<colorLine:TimeLineControl Height="100" TotalHours="6" />

看起来像:

enter image description here

所以问题是: 如何更改我的代码,使我的线条缩放以填充控件高度,但在宽度更改时保持现有行为(它们之间只有空间缩放,但不是线条)。

2 个答案:

答案 0 :(得分:1)

如果它只是一个以所示方式绘制刻度的控件,我想我会采用不同的方式并创建一个非常小的自定义控件。这就是你需要的,而且非常明显它是如何工作的。您可以根据需要添加依赖项属性(如课程时间)。只需使用这种方式就可以填满所有给定的空间。

public class HourTicks : FrameworkElement
{
    static HourTicks ()
    {
    }

    protected override void OnRender (DrawingContext drawingContext)
    {
        int hours = 10;
        Pen pen  = new Pen(Brushes.Black, 1);

        drawingContext.DrawLine (pen, new Point (0, 0), new Point (0, ActualHeight));
        drawingContext.DrawLine (pen, new Point (ActualWidth, 0), new Point (ActualWidth, ActualHeight));

        int numTicks = hours * 2;
        double delta = ActualWidth / numTicks;
        double x = delta;

        for (int i = 0; i <numTicks; i++)
        {
            drawingContext.DrawLine (pen, new Point (x, 0), new Point (x, ActualHeight / 3));
            x += delta;
            drawingContext.DrawLine (pen, new Point (x, 0), new Point (x, ActualHeight / 2));
            x += delta;
        }
    }
}

答案 1 :(得分:-1)

根据RenderSize.Height将Y1,Y2的设置更改为某个值。例如:

Y1 = Grid.RenderHeight - 40;
Y2 = Grid.RenderHeight - 20;

显然20&amp; 40切换为你现在'测量'要留下的空白量,而不是线的长度。