我有一个可以在可缩放的画布上绘制形状和图像的应用程序。我想知道将当前的方法从使用全局的瞬态设置对象改为使用继承的附加属性的影响。
解释:图形的一些方面(例如线宽,字体大小等)是用户可配置的,但也受缩放级别的影响。我很快发现,仅仅将我的形状的StrokeThickness绑定到配置值会导致问题。如果用户将画布放大或缩小,则厚度会发生变化。我希望它保持不变。
所以我选择了一个解决方案,将我的形状绑定到一个全局的,瞬态的“实时”设置,这些设置来自配置的设置和当前的缩放比例。当用户将画布放大或缩小时,代码隐藏会更改这些实时设置。
private void UpdateScaledSizesAfterZoom()
{
// Get the scale from the canvas' scale transform.
if (!(Scene.LayoutTransform is ScaleTransform st))
return;
var div = st.ScaleX > 0 ? st.ScaleX : 1;
// Update all live settings with the new scale.
LiveSettings.LineWidth = Settings.LineWidth/ div;
LiveSettings.FontSize = Settings.FontSize / div;
}
捆绑:
<Path StrokeThickness="{Binding Source={x:Static LiveSettings.Default}, Path=LineWidth}" Data=... blah blah blah .../>
这一切都运行得很好但是关于将我的所有对象绑定到全局对象的事情简直困扰我。如果我必须的话,我可以坚持下去,但我不介意更清洁。
所以我想知道一种使用WPF属性继承的方法;我可以,在我的画布上交替注册这样的属性作为继承的附加属性(“ShapeCanvas”)。然后我的形状可以绑定到“ShapeCanvas.LineWidth”,而不需要依赖某些全局设置对象的存在。
但是我可能有很多很多形状。所以我想知道这可能会如何影响性能。 WPF通过包含继承传播这样的属性有多贵?
我已经调试了一些附加属性如何工作,并且看起来当附加的继承属性发生变化时,继承上下文中的每个项都会得到通知。所以看起来这确实非常昂贵。我不想让我的变焦迟滞或任何东西。
有没有人有这方面的经验?这是值得关注的事吗?
这是一个非常简单的例子,说明如何转换Path的Geometry而不是Path元素本身,这样就不需要重新调整它的StrokeThickness:
<Window.Resources>
<MatrixTransform x:Key="GeometryTransform"/>
</Window.Resources>
<Canvas Background="Transparent" MouseWheel="Canvas_MouseWheel">
<Path Fill="Yellow" Stroke="Blue" StrokeThickness="3">
<Path.Data>
<PathGeometry Figures="M100,50 L150,100 100,150 50,100Z"
Transform="{StaticResource GeometryTransform}"/>
</Path.Data>
</Path>
</Canvas>
使用这个MouseWheel处理程序:
private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
var transform = (MatrixTransform)Resources["GeometryTransform"];
var matrix = transform.Matrix;
var scale = e.Delta > 0 ? 1.1 : 1 / 1.1;
var pos = e.GetPosition((IInputElement)sender);
matrix.ScaleAt(scale, scale, pos.X, pos.Y);
transform.Matrix = matrix;
}