Pergunta

Eu tenho um controle de usuário bastante simples que quero vincular um ScaleTransform Propriedade para um DP no código por trás do tipo:

<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>

E então, no código atrás, eu faço isso:

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

Mas recebi um erro dizendo:

Não é possível definir uma propriedade no objeto '...' porque está em um estado somente leitura.

Então eu mudei para:

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

Mas agora isso realmente não faz nada ... nenhuma escala é aplicada à minha tela.

CONTUDO

Se eu remover a ligação no ScaleTransform E apenas tive como um elemento XAML vazio:

<ScaleTransform />

Então, no meu código, faço isso:

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

Funciona! Eu recebo a escala aplicando

Então, 2 perguntas:

  1. Por que minha transformação é Frozen é o primeiro lugar?
  2. Por que meu encadernação não funciona quando clono a transformação?

Obrigado a todos!

ATUALIZAR:

Aqui está a definição do 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); }
        }
Foi útil?

Solução

O Scaletransform que você passa como seu valor padrão para sua propriedade ZoomTransform é congelado pelo PropertyMetadata. Uma vez que a propriedadeMetadata for passou para o método de registro será congelado/selado.

No entanto, uma vez que os metadados são consumidos como parte de uma chamada para se registrar, addwner ou substituir o sistema de propriedades, o sistema de propriedade selará a instância dos metadados e as propriedades agora são consideradas imutáveis. Tentar definir o DefaultValue depois que a emissão é verdadeira nesta instância de metadados aumentará uma exceção.

Como o Scaletransform é congelável, ele é congelado como parte desse processo.

Quanto à sua segunda pergunta, com base no código que você forneceu, aplica corretamente o Scaletransform ao clonar o ZoomTransform. Deve haver algo mais acontecendo que você não incluiu.

Isso supõe que o XAML para o seu UserControl inclua um atributo X: Classe que se vincula ao arquivo de código-behind para o RoundByRoundControl.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top