C# 我可以在自定义WPF画布控件中绘制点网格吗?

C# 我可以在自定义WPF画布控件中绘制点网格吗?,c#,wpf,canvas,custom-controls,C#,Wpf,Canvas,Custom Controls,我构建了一个从画布继承的自定义控件。它使用ArrangeOverride方法向所有子元素添加拖放功能,这包括网格捕捉到50像素和一些其他自定义行为,例如保持元素位置 我真正想做的是扩展它,这样在拖动时,它会在背景中显示一个由点或十字组成的网格,以便您可以看到捕捉点的位置 但是,我无法修改控件的模板,因为它是一个面板。我尝试将其设置为包含画布的自定义控件,并将IEnumerable items源代码传递给它,但要了解集合的变化,以及集合中包含的模型而不是框架元素,这变得非常棘手 所以我不确定我应该

我构建了一个从画布继承的自定义控件。它使用ArrangeOverride方法向所有子元素添加拖放功能,这包括网格捕捉到50像素和一些其他自定义行为,例如保持元素位置

我真正想做的是扩展它,这样在拖动时,它会在背景中显示一个由点或十字组成的网格,以便您可以看到捕捉点的位置

但是,我无法修改控件的模板,因为它是一个面板。我尝试将其设置为包含画布的自定义控件,并将IEnumerable items源代码传递给它,但要了解集合的变化,以及集合中包含的模型而不是框架元素,这变得非常棘手

所以我不确定我应该走哪条路。感觉好像有一个我忽略了的非常简单的解决方案,所以我愿意接受建议


提前感谢。

我曾经做过类似的事情:在UserControl上绘制网格线,然后在上面添加控件。这是一个简单的调度程序应用程序,用于分配谁将在本月的哪个班次工作。我必须有列标题(天)和行标题(人)以及一个可滚动的网格,我可以在其中添加/删除控件。我不知道我的解决方案能在多大程度上帮助你,但它就在这里

我使用来自的
HeaderedScrollViewer
UCHeader
是一个
UserControl
,带有带日期的旋转文本框。神奇发生在UC\U网格线中

<Grid>
    <lib:HeaderedScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Background="AliceBlue">
    <lib:HeaderedScrollViewer.TopHeader>
        <lib:UCHeader Name="ucHeader"/>
    </lib:HeaderedScrollViewer.TopHeader>
    <lib:HeaderedScrollViewer.LeftHeader>
        <Border BorderBrush="Black" BorderThickness="1,2,1,1">
            <StackPanel Orientation="Vertical"  Name="spRows" />
        </Border>
    </lib:HeaderedScrollViewer.LeftHeader>
    <Grid Name="gridContentAll">
        <Border Canvas.ZIndex="1"  Background="Transparent"
            BorderThickness="1,1,1,2" BorderBrush="Transparent">
                <Grid ClipToBounds="True" Name="gridContent"  Background="Transparent" />
        </Border>
        <Border Canvas.ZIndex="0" BorderThickness="1,1,1,2" BorderBrush="Black" Background="White">
            <lib:UC_GridLines Name="ucGridLines" BorderThickness="0"/>
        </Border>
    </Grid>
</lib:HeaderedScrollViewer>
</Grid>

谢谢你,艾莉,这真的很有帮助。我刚刚覆盖了自定义控件的OnRender方法,并添加了一个网格。你知道我怎么只能在用户主动拖动时显示网格吗?该render方法仅在最初调用,然后在调整控件大小时调用。理想情况下,能够展示和隐藏它将是一件很棒的事情。没关系——呆在那里其实很好。我把它做得很微妙。我还必须在末尾添加base.OnRender(drawingContext),否则由于某些原因,拖拽/网格捕捉性能非常差。再次感谢您提供的代码示例。
    protected override void OnRender(DrawingContext drawingContext)
    {
        // VM contains data of the grid, used to draw gridlines
        // such as number of days etc.
        if (this.VM == null)
        {
            base.OnRender(drawingContext);
            return;
        }
        double dpiFactor = 1;
        try
        {
            Matrix m = PresentationSource.FromVisual(this)
                     .CompositionTarget.TransformToDevice;
            dpiFactor = 1 / m.M11;
        }
        catch { }

        Pen pen = new Pen(Brushes.Black, 1 * dpiFactor);
        double halfPenWidth = pen.Thickness / 2;

        GuidelineSet guidelines = new GuidelineSet();

        double width = this.VM.Days.Count * this.VM.DayWidth - 16 * (this.VM.DayWidth / 24);
        double height = this.VM.RowHeight * rowCount;

        for (int i = 1; i < this.VM.Days.Count; i++)
        {
            guidelines.GuidelinesX.Add(i * this.VM.DayWidth + halfDashPenWidth);
        }

        for (int i = 1; i < rowCount; i++)
        {
            guidelines.GuidelinesY.Add(i * this.VM.RowHeight + halfPenWidth);
        }

        drawingContext.PushGuidelineSet(guidelines);

        for (int i = 1; i < this.VM.Days.Count; i++)
        {
            drawingContext.DrawLine(dashpen, new Point(i * this.VM.DayWidth, 0), new Point(i * this.VM.DayWidth, height));
        }

        for (int i = 1; i < rowCount; i++)
        {
            drawingContext.DrawLine(pen, new Point(0, i * this.VM.RowHeight), new Point(width, i * this.VM.RowHeight));
        }

        drawingContext.Pop();
    }