C# 如何获得未渲染元素的预期宽度和高度?

C# 如何获得未渲染元素的预期宽度和高度?,c#,wpf,C#,Wpf,所以我有一个画布,我想在上面画16条垂直线。画布还位于名为TimeLine的用户控件元素的顶部。如果我在XAML中手动创建行,它们在用户控件顶部可见,因此这不是问题所在。这些行是以编程方式创建的,并存储在绑定到ItemsControl的ObservableCollection中。由于我希望所有行之间的间距相同(我特别希望16行),因此我使用画布的ActualWidth属性。但是,我的行创建方法似乎在呈现画布之前运行,因此ActualWidth返回null(我认为,在调试时,它只是说不是数字),因

所以我有一个画布,我想在上面画16条垂直线。画布还位于名为TimeLine的用户控件元素的顶部。如果我在XAML中手动创建行,它们在用户控件顶部可见,因此这不是问题所在。这些行是以编程方式创建的,并存储在绑定到ItemsControl的ObservableCollection中。由于我希望所有行之间的间距相同(我特别希望16行),因此我使用画布的ActualWidth属性。但是,我的行创建方法似乎在呈现画布之前运行,因此ActualWidth返回null(我认为,在调试时,它只是说不是数字),因此我的行的长度为0,不可见。是否有任何方法可以等待画布渲染或在大小更改时收到通知?我不想使用特定的像素量,因为我需要一个响应性的布局

我尝试将DrawTimeLineGridLines()设置为页面加载事件的事件处理程序,但没有任何效果

XAML


MyCustomLine

类MyCustomLine
{
来自{get;set;}的公共点
指向{get;set;}的公共点
公共笔刷{get;set;}
公共双冲程厚度{get;set;}
}    
视图模型

private observetecollection gridLines=new observetecollection();
公共可观测收集时间线网格线
{
获取{返回网格线;}
设置
{
如果(网格线!=值)
{
网格线=值;
OnPropertyChange();
}
}
}
XAML.cs

private void DrawTimeLineGridLines()
{
var gridLines=新的ObservableCollection();
双水平间距=网格画布。宽度/15;

对于(int i=0;i,以下XAML绘制了一组垂直线,无需任何手动大小或位置计算:

<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Width="3" Fill="DarkBlue"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

您可能希望使用
n-1
线条绘制
n
项,以便在左右边缘上获得均匀间隔的间隙。为此,请将矩形左对齐,不要绘制第一个:

<ItemsControl ItemsSource="{Binding}" AlternationCount="1000000">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Style.Triggers>
                <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                    <Setter Property="Visibility" Value="Hidden"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Width="3" Fill="DarkBlue"
                       HorizontalAlignment="Left" Margin="-1.5,0,0,0"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>


是的,谢谢,这是我想弄明白的事情之一。但我真的很喜欢虚线。所以我尝试用一条线替换数据模板,但它没有画出它们?我将尝试在数据模板中的矩形上做一个边框,看看是否可行。只需使用一条很长的线,例如
<ItemsControl ItemsSource="{Binding}" AlternationCount="1000000">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Style.Triggers>
                <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                    <Setter Property="Visibility" Value="Hidden"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Width="3" Fill="DarkBlue"
                       HorizontalAlignment="Left" Margin="-1.5,0,0,0"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>