C# WPF的时间表

C# WPF的时间表,c#,wpf,data-binding,datagrid,C#,Wpf,Data Binding,Datagrid,我正在使用DataGrid控件开发一个时间轴应用程序,但我找不到在单元格中插入和绑定Canvas控件的方法。我应该使用另一个控件吗 绘制时间线有两种方法 数据绑定与代码隐藏 第一种方法是使用数据绑定,这一方法已经进行了一半;通过这种方式,您可以定义数据模型和数据模板,模型中的条目可能具有类似于Name、Born和marred的属性,并且Born和marred具有类似1980的整数值以指示年份,而数据模板定义了条目的视觉呈现方式 另一种方法是使用代码隐藏,构建画布,并在画布上绘制线条和标签。

我正在使用
DataGrid
控件开发一个时间轴应用程序,但我找不到在单元格中插入和绑定
Canvas
控件的方法。我应该使用另一个控件吗



绘制时间线有两种方法

数据绑定与代码隐藏

第一种方法是使用数据绑定,这一方法已经进行了一半;通过这种方式,您可以定义数据模型和数据模板,模型中的条目可能具有类似于NameBornmarred的属性,并且Bornmarred具有类似1980的整数值以指示年份,而数据模板定义了条目的视觉呈现方式

另一种方法是使用代码隐藏,构建
画布
,并在
画布
上绘制线条和标签。。。使用C#,然后将
画布
插入到
数据网格
单元格中

问题:

现在您陷入了困境,因为您希望将它们混合在一起,首先使用数据绑定来填充数据模型中
DataGrid
中的一些行,每一行都有一个
Name
标签和一个
Canvas
,然后您希望访问
Canvas
以使用代码隐藏进行绘图。由于
Canvas
是使用数据绑定创建的,因此很难获取对它的引用,甚至不能使用名称
TimelineCanvas
访问它,因为该名称具有“模板范围”——这意味着只能从模板内访问它

可以使用VisualTreeHelper从代码隐藏访问画布。请参阅如何:。但我不推荐这种“混合方法”

解决方案

坚持数据绑定(如果您熟悉XAML)或代码隐藏

如果选择数据绑定,请在
数据模板
中添加行和标签,当然您需要通过绑定到模型中的某些属性来计算它们在画布上的位置

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Canvas Name="TimelineCanvas">
            <Label Content="Born" Canvas.X="30" Canvas.Y="20" />
            <Line
                X1="10" Y1="30"
                X2="350" Y2="30"
                Stroke="Blue"
                StrokeThickness="1" />
            <!--The whole data template can be quite complicated, but here I just hard code a label and a line to get you started-->
        </Canvas>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

在我看来,这两种方法都是非常具有挑战性的,您可以为
时间线定义用户控件,因此可以将构造逻辑隔离在一个单独的类中

这里有什么问题?你的意思是不能将
Canvas
放在
DataGrid
单元格的正确位置吗?请显示代码以帮助解释问题。我添加了当前的示例代码。现在,我想添加行并访问每个“画布”以绘制时间线。但你想从代码隐藏中执行这些操作,而你在访问画布时遇到了问题,这就是你的问题吗?@Kaspar:是的,这是我的问题,但正如kennyzx所说,访问
数据网格
单元格中的控件似乎很困难或可能不可能。@carlos,可以从代码隐藏处访问
画布
,请参见,但您还有其他问题,这就是为什么我不建议这样做的原因。对于
时间线
的用户控件,我应该如何从代码隐藏中初始化或添加事件?定义一个用户控件,自动生成两个文件…这与在
MainPage.xaml
MainPage.xaml.cs
中执行的操作大致相同,在构造函数中初始化,在xaml中添加事件。。。
<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Canvas Name="TimelineCanvas">
            <Label Content="Born" Canvas.X="30" Canvas.Y="20" />
            <Line
                X1="10" Y1="30"
                X2="350" Y2="30"
                Stroke="Blue"
                StrokeThickness="1" />
            <!--The whole data template can be quite complicated, but here I just hard code a label and a line to get you started-->
        </Canvas>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Canvas Name="TimelineCanvas"></Canvas>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>