WPF, почему мой ScaleTransform заморожен и как я могу к нему привязаться? - PullRequest
5 голосов
/ 17 февраля 2010

У меня есть довольно простой пользовательский элемент управления, который я хочу связать свойством 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. Почему моя привязка не работает, когда я клонирую преобразование?

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

UPDATE:

Вот определение ДП:

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); }
        }

1 Ответ

1 голос
/ 19 мая 2011

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

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

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

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

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

...