我构建了一个继承自 Canvas 的自定义控件。它使用 ArrangeOverride 方法向所有子元素添加拖放功能,这包括网格对齐到 50 像素以及一些其他自定义行为,例如保留元素位置。
我真正想做的是扩展它,以便在拖动时,它在背景中显示点或十字网格,以便您可以看到捕捉点的位置。
但是,我无法修改控件的模板,因为它是一个面板。我尝试将其设为包含 Canvas 的自定义控件,并传递 IEnumerable 项目源,但要了解集合的变化变得非常棘手,而且集合随后包含模型而不是框架元素。
所以我不确定我应该走哪条路。感觉好像可能有一个非常简单的解决方案被我忽略了,所以我愿意接受建议!
提前致谢。
最佳答案
我曾经做过类似的事情:在 UserControl 上绘制网格线,然后在其顶部添加控件。这是一个简单的调度应用程序,用于分配谁将在当月的哪个类次工作。我必须有列标题(天)和行标题(人)和内部可滚动网格,我可以在其中添加/删除控件。我不知道我的解决方案能在多大程度上帮助您,但它就是这样。
我使用HeaderedScrollViewer
来自here 。 UCHeader
是 UserControl
带有带有日期的旋转文本框。奇迹发生在 UC_GridLines
.
<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>
这里重要的是:
- 设置
Background="Transparent"
对于包含子控件的控件 - 正确设置 ZIndex,以便控件显示在网格上。
- 设置
SnapsToDevicePixels="True"
和UseLayoutRounding="True"
在根元素上(例如 WIndow)
UC_GridLines 在其 .xaml 文件中没有任何内容(只有 <Grid></Grid>
)。绘制网格线发生在代码隐藏中:
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();
}
关于c# - 我可以在自定义 WPF Canvas 控件中绘制点网格吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39370550/