Являются ли свойства наследуемых вложенных зависимостей WPF "дорогими"? - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть рабочее приложение, которое рисует фигуры и изображения на масштабируемом холсте.Я задаюсь вопросом о последствиях изменения моего текущего подхода от использования глобального объекта временных параметров настройки к использованию унаследованных вложенных свойств.

Объяснение: несколько аспектов рисования (например, ширина линии, размеры шрифта и т. Д.)) настраиваются пользователем, но также зависит от уровня масштабирования.Я быстро обнаружил, что простая привязка, скажем, 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 для распространения такого свойства через наследование содержимого?

Я уже отладил некоторые из свойств работы прикрепленных свойств, и кажется, что когда изменяется присоединенное наследуемое свойство, буквально каждый элемент в наследованииконтекст получает уведомление об этом.Похоже, это может быть довольно дорого.Я не хотел бы делать масштабирование медленным или что-то в этом роде.

У кого-нибудь есть опыт с такими проблемами?Это то, что беспокоит.

1 Ответ

0 голосов
/ 18 сентября 2018

Вот очень простой пример того, как преобразовать Geometry of Path вместо самого элемента 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;
}
...