让我们说canvas canvas的值为left = 50,top = 50当canvas的宽度= 500时。当canvas调整大小时,如何设置相对于画布宽度的左侧和顶部位置。
如果用户在大窗口中运行应用程序或调整窗口大小,则画布子项的左侧和顶部位置会混乱。如何重新排列画布儿童的左侧和顶部位置
答案 0 :(得分:1)
您可以使用覆盖OnPropertyChanged制作自定义画布,如下所示:
CTE Scan on search_graph (cost=1705.74..1707.36 rows=81 width=40) (actual time=0.066..1.231 rows=6 loops=1)
CTE search_graph
-> Recursive Union (cost=0.00..1705.74 rows=81 width=40) (actual time=0.055..1.206 rows=6 loops=1)
-> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.030..0.031 rows=1 loops=1)
-> Hash Left Join (cost=102.95..170.41 rows=8 width=40) (actual time=0.226..0.370 rows=2 loops=3)
Hash Cond: (sg."NODE" = cnt.node)
Filter: (((be.flag_one = 1) AND (cno.node IS NULL)) OR ((be.flag_two = 1) AND (cnt.node IS NULL)))
Rows Removed by Filter: 16
-> Hash Join (cost=42.10..47.71 rows=136 width=56) (actual time=0.161..0.279 rows=18 loops=3)
Hash Cond: (be.source_id = sg."NODE")
Join Filter: (be.target_id <> ALL (sg."PATH"))
-> Seq Scan on teste_bidirectional_edges be (cost=0.00..1.81 rows=41 width=16) (actual time=0.084..0.197 rows=54 loops=2)
Filter: ((flag_one = 1) OR (flag_two = 1))
-> Hash (cost=41.68..41.68 rows=34 width=44) (actual time=0.084..0.084 rows=1 loops=3)
Buckets: 1024 Batches: 1 Memory Usage: 8kB
-> Hash Right Join (cost=0.26..41.68 rows=34 width=44) (actual time=0.062..0.065 rows=1 loops=3)
Hash Cond: (cno.node = sg."NODE")
-> Seq Scan on teste_censored_nodes_one cno (cost=0.00..32.60 rows=2260 width=4) (actual time=0.029..0.034 rows=1 loops=2)
-> Hash (cost=0.22..0.22 rows=3 width=40) (actual time=0.021..0.021 rows=1 loops=3)
Buckets: 1024 Batches: 1 Memory Usage: 8kB
-> WorkTable Scan on search_graph sg (cost=0.00..0.22 rows=3 width=40) (actual time=0.009..0.010 rows=1 loops=3)
Rows Removed by Filter: 1
-> Hash (cost=32.60..32.60 rows=2260 width=4) (actual time=0.074..0.074 rows=1 loops=1)
Buckets: 4096 Batches: 1 Memory Usage: 33kB
-> Seq Scan on teste_censored_nodes_two cnt (cost=0.00..32.60 rows=2260 width=4) (actual time=0.057..0.060 rows=1 loops=1)
Planning time: 1.924 ms
Execution time: 1.707 ms
然后使用YourCustomCanvas代替项目中的Canvas,如下所示:
public class YourCustomCanvas : Canvas
{
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
var ep = e.Property;
if (ep != null)
{
if(ep.Name == "Left")
foreach (FrameworkElement child in Children)
SetLeft(child, GetLeft(child) / (double)e.OldValue * (double)e.NewValue);
else if (ep.Name == "Top")
foreach (FrameworkElement child in Children)
SetTop(child, GetTop(child) / (double)e.OldValue * (double)e.NewValue);
}
}
}
答案 1 :(得分:0)
我将提供建议,但由于该问题使我们无法在现有代码方面使用任何内容,因此在更新问题之前,我无法提供任何特定/完整的代码。
拖放界面,如果使用MVVM模式正确完成,可能涉及ItemsControl
(或从中派生的内容)ItemsPanelTemplate
为Canvas
。绑定必须提供Left
和Top
展示位置,可能占画布尺寸的百分比,例如
...
<ItemsControl.ItemContainerStyle>
<Style>
...
<Setter Property="Canvas.Left">
<Setter.Value>
<MultiBinding Converter="{StaticResource RelativePositionConverter}">
<MultiBinding.Bindings>
<Binding Path="Left" />
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}" />
</MultiBinding.Bindings>
</MultiBinding>
</Setter.Value>
</Setter>
<Setter Property="Canvas.Top">
<Setter.Value>
<MultiBinding Converter="{StaticResource RelativePositionConverter}">
<MultiBinding.Bindings>
<Binding Path="Top" />
<Binding Path="ActualHeight" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}" />
</MultiBinding.Bindings>
</MultiBinding>
</Setter.Value>
</Setter>
...
</Style>
</ItemsControl.ItemContainerStyle>
...
然后,您需要创建一个实现IMultiValueConverter
的类(我在该XAML中碰巧调用StaticResource
的{{1}}),该类乘以第一个值(相对位置;两个值之间的值) 0和1)通过第二个值(画布的宽度或高度)来获得正确的位置。请注意,您无法真正实现RelativePositionConverter
,因此启用拖动功能的ConvertBack
代码必须使用类似的数学运算来设置支持值。
有许多活动部件可以实现这一目标,但我认为我已经提供了足够的信息来帮助您走上正确的道路。如果您对如何进行绑定,转换器,大拇指,控制模板等方面有进一步的疑问,最好使用更具体的信息创建新问题。