【问题标题】:Are WPF Inherited Attached Dependency properties "expensive"?WPF 继承的附加依赖属性是否“昂贵”?
【发布时间】:2018-09-17 19:22:42
【问题描述】:

我有一个可以在可缩放画布上绘制形状和图像的工作应用。我想知道将我当前的方法从使用全局临时设置对象更改为使用继承的附加属性会产生什么影响。

解释一下:绘图的一些方面(例如线宽、字体大小等)是用户可配置的,但会受到缩放级别的影响。我很快发现仅仅将我的形状的 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 通过包含继承来传播这样的属性有多昂贵?

我已经调试了一些附加属性的工作方式,并且似乎当附加的继承属性发生更改时,继承上下文中的每个项目都会收到有关它的通知。所以看起来这确实很昂贵。我不想让我的缩放滞后或任何东西。

有没有人遇到过此类问题?这有什么要注意的吗?

【问题讨论】:

  • 整个方法都是错误的。你应该有一个带有变换几何的路径,而不是一个 RenderTransform-ed 路径。是的,属性值继承很昂贵:docs.microsoft.com/en-us/dotnet/api/…
  • 为什么会出错?
  • 因为当你在路径数据中转换几何而不是整个路径时,根本不需要调整 StrokeThickness。它只会保持其价值。 True 设置几何的变换属性。
  • 我不知道我什至可以做到这一点。我只是想,“缩放整个场景,一切都会随之缩放”,然后当然遇到了线条粗细问题。可悲的是,我现在无法改变事情,但当我有空缺时,我会尝试对此进行调查。
  • 哦,我忘了贴一个简单的例子。我会尽快给你一个想法。

标签: wpf data-binding attached-properties


【解决方案1】:

这里是一个非常简单的例子,说明如何转换路径的几何图形而不是路径元素本身,从而避免重新缩放其 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;
}

【讨论】:

  • 好悲伤就是这么简单。我不敢相信我花了这么多时间做我所做的事情
猜你喜欢
  • 1970-01-01
  • 2013-04-01
  • 2011-12-06
  • 1970-01-01
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多