【发布时间】:2018-02-27 14:35:57
【问题描述】:
我在 ItemsControl 中有一个 Canvas 设置,我用按钮填充它。每个按钮都有一个 X 和 Y 位置属性,用于在画布上定位按钮。
我试图做的是使项目位置相对于画布的大小。我的问题是当我调整画布大小时,按钮 ViewModel 没有收到 NotifyPropertyChanged 调用,因此它们的位置永远不会更新。
<ItemsControl ItemsSource="{Binding Buttons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Top" Value="{Binding PosY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Setter Property="Canvas.Left" Value="{Binding PosX, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:ToggleButton}">
<local:ToggleButton DataContext="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
在 ToggleButtonViewModel 中:
public double PosY {
get {
return (_Button.PositionVertical * Size[1]);
}
}
public double PosX {
get { return (_Button.PositionHorizontal * Size[0]); }
}
Size 是一个 double[],具有画布的 X 和 Y 尺寸。我已经尝试将它存储在 CanvasViewModel 中,在这种情况下,我可以使用画布上的 SizeChanged 事件对其进行更新,但后来我不知道如何在大小更改时更新 ToggleButtonViewModel 中的 PosX 和 PosY。 我还尝试将大小作为静态参数存储在所有 ToggleButtonViewModel 中,但我无法使用带有静态参数的 NotifyPropertyChanged。
有什么想法可以让 PosX 和 PosY 在画布大小发生变化时更新?
【问题讨论】:
-
ItemsSource="{Binding Buttons}" 是您的项目控件中的数据上下文。所以 DataContext="{Binding}" 没用。如果你想使用 PosY 或 PosX,你已经在绑定过程中正确设置了数据上下文
-
请注意,设置
Mode=TwoWay和UpdateSourceTrigger=PropertyChanged是没有意义的。即使 UI 更改了 Top 或 Left 属性,对只读属性的双向绑定也毫无意义。而UpdateSourceTrigger=PropertyChanged与INotifyPropertyChanged接口的PropertyChanged事件完全没有关系。 -
与其在 Canvas 大小变化时尝试更新 PosX 和 PosY,不如创建一个 custom Canvas 来处理 Left 和 Top(或其自己的一组附加属性)作为相对值范围 0..1。只需从 Canvas(或 Panel)派生并覆盖 ArrangeOverride。
标签: c# wpf inotifypropertychanged