我有一个ItemsControl
,Canvas
为ItemsPanel
,Path
为ItemTemplate
。目标是绘制图形,因此Path.Data
应包含要使用绝对坐标在“画布”中绘制的几何体。
如果我实例化Canvas并将路径直接放在其中,它就可以正常工作。
但是如果我使用ItemsControl,则每个Path最终都会包含在ContentPresenter中,然后坐标会丢失,因为ContentPresenter会与Canvas原点对齐。
这是我的代码:
<ItemsControl
ItemsSource="{Binding Signals}"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Path
Stroke="Red"
StrokeThickness="1"
StrokeDashCap="Round"
StrokeLineJoin="Round"
Stretch="Fill"
Data={Binding Converter=SignalToGeometryConverter}
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
答案 0 :(得分:3)
如果你确实需要Canvas
ItemsPanel
ItemsControl
,{em>和,你真的需要填写父母,你可能是在一个艰难的地方。如果您Grid
ItemsPanel
可以获得ContentPresenter
,那么您已经完成了设置。
你在这里得到的不是Stretch
,而是Path
。这导致"M 100,100 L 200,200"
填补其父级 - 但不是你想象的方式。除了Stretch
以外的任何None
,Stretch="Fill"
将从父级的左上角开始绘制一条线。它将使用的边界框是路径几何实际使用的最大和最小x和y值。它假设你只关心你打扰去的地方。如果您正在叠加多个具有不同左上角(和右下)边界的路径,则它们将被缩放并以不同方式进行偏移,从而对所有内容进行总哈希处理。
当你想到它时,即使伸展确实从0,0开始,它怎么会知道用于右下界?这些路径彼此不了解。如果你有一个Path,并将你当前的每个东西作为一个不同的数字添加到它,那将是一回事。但是这样,他们没有意识到共同的参考框架。
所以最快的解决方法是删除Canvas
,但是什么都不会延伸。只要您使用ItemsPanel
作为M 0,0 M xmax,ymax
,您也可以不尝试延伸路径,因为(据我所知,通过测试)它们无论如何都不会伸展那种情况。
如果你想要伸展,首先你需要所有的路径都有相同的边界框,无论它们是否实际使用整个东西。这意味着首先计算您将需要多少水平和垂直空间,并使用
为每个路径数据添加前缀Path
...在移动到实际点之前,您要启动Canvas
at。
然后将Grid
更改为<Grid>
<ItemsControl
ItemsSource="{Binding Signals, RelativeSource={RelativeSource AncestorType=Window}}"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Path
Stroke="DeepSkyBlue"
StrokeThickness="1"
Data="{Binding}"
Stretch="Fill"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
。
以下是我测试过的代码:
XAML
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
int left = 10;
int top = 100;
int bottom = 200;
var signals =
Enumerable.Range(0, 19)
.Select(n => $"M 0,0 M 300,300 M {(n * 10) + left},{top} L {(n * 15) + left},{bottom}")
.ToList();
// Show shared bounding box
signals.Add("M 0,0 L 300,0 L 300,300 L 0,300 Z");
Signals = signals;
}
public IList Signals
{
get { return (IList)GetValue(SignalsProperty); }
set { SetValue(SignalsProperty, value); }
}
public static readonly DependencyProperty SignalsProperty =
DependencyProperty.Register("Signals", typeof(IList), typeof(MainWindow),
new PropertyMetadata(null));
}
C#
services=["service1","service2","service3"]
ports=[11001,11002,11003]