WPF почему моя ScaleTransform заморожена и как я могу привязаться к ней?

StackOverflow https://stackoverflow.com/questions/2277399

Вопрос

У меня есть довольно простой пользовательский элемент управления, который я хочу привязать к ScaleTransform свойство для DP в коде, лежащем в основе, вот так:

<UserControl 
x:Name="RoundByRound"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
...
>

<Canvas x:Name="MyCanvas">
  <Canvas.RenderTransform>
    <TransformGroup>
      <ScaleTransform ScaleX="{Binding ZoomTransform.ScaleX, ElementName=RoundByRound}" 
                      ScaleY="{Binding ZoomTransform.ScaleY, ElementName=RoundByRound}"/>
      <SkewTransform/>
      <RotateTransform/>
      <TranslateTransform X="{Binding TranslateTransform.X, ElementName=RoundByRound}" 
                          Y="{Binding TranslateTransform.Y, ElementName=RoundByRound}"/>
     </TransformGroup>
   </Canvas.RenderTransform>
</Canvas>
</UserControl>

и затем в коде, лежащем в основе, я делаю это:

ZoomTransform.ScaleX = 3;
ZoomTransform.ScaleY = 3;

Но я получил сообщение об ошибке, в котором говорится:

Не удается установить свойство для объекта '...', поскольку он находится в состоянии только для чтения.

Поэтому я изменил его на:

var cloned = ZoomTransform.Clone();
cloned.ScaleX = 3;
cloned.ScaleY = 3;
ZoomTransform = cloned;

Но теперь это на самом деле ничего не дает...никакой масштаб не наносится на мой холст.

ОДНАКО

Если я удалю привязку на ScaleTransform и просто используйте его как пустой элемент XAML:

<ScaleTransform />

Затем в моем коде я делаю это:

(MyCanvas.RenderTransform as TransformGroup).Children[0] = new ScaleTransform(3, 3);

Это работает!Я применяю шкалу

Итак, 2 вопроса:

  1. Почему моя Трансформация Frozen это первое место?
  2. Почему моя привязка не работает, когда я клонирую преобразование?

Спасибо всем!

Обновить:

Вот определение DP:

public static readonly DependencyProperty TranslateTransformProperty = DependencyProperty.Register("TranslateTransform",
            typeof(TranslateTransform),
            typeof(RoundByRoundControl),
            new PropertyMetadata(new TranslateTransform { X = 0, Y = 0 }));

        public static readonly DependencyProperty ZoomTransformProperty = DependencyProperty.Register("ZoomTransform",
            typeof(ScaleTransform),
            typeof(RoundByRoundControl),
            new PropertyMetadata(new ScaleTransform { ScaleX = 1, ScaleY = 1 }));

        public TranslateTransform TranslateTransform
        {
            get { return (TranslateTransform)GetValue(TranslateTransformProperty); }
            set { SetValue(TranslateTransformProperty, value); }
        }

        public ScaleTransform ZoomTransform
        {
            get { return (ScaleTransform)GetValue(ZoomTransformProperty); }
            set { SetValue(ZoomTransformProperty, value); }
        }
Это было полезно?

Решение

ScaleTransform, который вы передаете в качестве значения по умолчанию для вашего свойства ZoomTransform, заблокирован PropertyMetadata .Как только PropertyMetadata будет передается в метод Register это будет заморожено / запечатано.

Однако, как только метаданные будут использованы как часть вызова Register, AddOwner или OverrideMetadata, система свойств запечатает это экземпляр метаданных и свойства теперь считаются неизменяемыми.Попытка установить значение по умолчанию один раз IsSealed имеет значение true для этих метаданных экземпляр вызовет исключение.

Поскольку ScaleTransform является замораживаемой формой, она замораживается как часть этого процесса.

Что касается вашего второго вопроса, основываясь на предоставленном вами коде, он правильно применяет ScaleTransform при клонировании ZoomTransform.Должно быть, происходит что-то еще, что вы не включили.

Это предполагает, что XAML для вашего UserControl включает атрибут x: Class, который связан с файлом кода для RoundByRoundControl.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top