C# 当RenderTransform.Changed在初始时间未满足设计器的XAML模式时,它的订阅将丢失

C# 当RenderTransform.Changed在初始时间未满足设计器的XAML模式时,它的订阅将丢失,c#,wpf,xaml,events,user-controls,C#,Wpf,Xaml,Events,User Controls,在我的用户控件中,我想了解WPF设计器中的旋转和协同。因此,在我的用户控制中,我做到了: private void Test_Loaded(object sender, RoutedEventArgs e) { this.RenderTransform.Changed += this.RenderTransform_Changed; } private void RenderTransform_Changed(object sender, Eve

在我的用户控件中,我想了解WPF设计器中的旋转和协同。因此,在我的用户控制中,我做到了:

    private void Test_Loaded(object sender, RoutedEventArgs e)
    {
        this.RenderTransform.Changed += this.RenderTransform_Changed;
    }

    private void RenderTransform_Changed(object sender, EventArgs e)
    {
        // do anything
    }
似乎
这个.RenderTransform
从来都不是空的。但是,除非我的用户控件具有与设计器在旋转控件时相同的XAML结构,否则它将失败

示例: 当我打开包含以下内容的XAML文件时:

<my:Test>
    <my:Test.RenderTransform>
        <TransformGroup>
            <ScaleTransform/>
            <SkewTransform/>
            <RotateTransform/>
            <TranslateTransform/>
        </TransformGroup>
    </my:Test.RenderTransform>
</my:Test>

有了这些,我试着在初始时间为任何给定的
RenderTransform
结构做好准备。但是设计者似乎并不关心
RenderTransform
对象中的实际内容,而是简单地重写它,因为XAML仍然不能满足它想要的结构


我能做些什么来解决这个问题?

除非我对这个问题的诊断是错误的,否则这里有一个答案:

问题

无论何时向
this.RenderTransform.Changed+=…
注册处理程序,您都会订阅一个对象,该对象是
this.RenderTransform
的值。当属性发生更改时,它不再保存您订阅的对象(该对象不再有效),但您仍然订阅了该对象,而不是属性的新值

解决方案

为了跟踪
RenderTransform
的实际值,您需要为“ValueChanged”事件向其所有者(通常是
窗口
控件
)订阅,并在每次发生该事件时注册
RenderTransform.Changed
处理程序。由于
RenderTransform
是名为
RenderTransformProperty
DependencyProperty
的“快捷方式属性”,因此需要这样做:

//inside the constructor
{
    DependencyPropertyDescriptor
        .FromProperty(RenderTransformProperty)
        .AddValueChanged(this, new EventHandler(RenderTransformPropertyChanged));
}

private void RenderTransformPropertyChanged(object sender, EventArgs e)
{
    //this.RenderTransform.Changed += ...
}

其中
dependencPropertyDescriptor
位于
System.ComponendModel
命名空间中。

除非我对问题的诊断有误,否则以下是答案:

问题

无论何时向
this.RenderTransform.Changed+=…
注册处理程序,您都会订阅一个对象,该对象是
this.RenderTransform
的值。当属性发生更改时,它不再保存您订阅的对象(该对象不再有效),但您仍然订阅了该对象,而不是属性的新值

解决方案

为了跟踪
RenderTransform
的实际值,您需要为“ValueChanged”事件向其所有者(通常是
窗口
控件
)订阅,并在每次发生该事件时注册
RenderTransform.Changed
处理程序。由于
RenderTransform
是名为
RenderTransformProperty
DependencyProperty
的“快捷方式属性”,因此需要这样做:

//inside the constructor
{
    DependencyPropertyDescriptor
        .FromProperty(RenderTransformProperty)
        .AddValueChanged(this, new EventHandler(RenderTransformPropertyChanged));
}

private void RenderTransformPropertyChanged(object sender, EventArgs e)
{
    //this.RenderTransform.Changed += ...
}

其中
DependencyPropertyDescriptor
位于
System.ComponendModel
命名空间中。

Grx70的解决方案给了我正确的方向,但是我覆盖了
属性元数据
,以避免重设
渲染转换

所以我做了

        Control.RenderTransformProperty.OverrideMetadata(typeof(Test), new PropertyMetadata(
                Control.RenderTransformProperty.GetMetadata(typeof(Test)).DefaultValue
                , new PropertyChangedCallback(Test.RenderTransform_Changed)
            )
        );
在我控件的静态构造函数中。这样我就可以做了

    protected static void RenderTransform_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Test obj = (Test)d; // my control
        Transform x = obj.RenderTransform; // new rendertransform
        if (x.IsFrozen == false)
        {
            x.Changed += obj.RenderTransform_Changed;
        }
        // do anything
    }

Grx70的解决方案给了我正确的方向,但是我覆盖了
属性元数据
,以消除
渲染转换
的重置

所以我做了

        Control.RenderTransformProperty.OverrideMetadata(typeof(Test), new PropertyMetadata(
                Control.RenderTransformProperty.GetMetadata(typeof(Test)).DefaultValue
                , new PropertyChangedCallback(Test.RenderTransform_Changed)
            )
        );
在我控件的静态构造函数中。这样我就可以做了

    protected static void RenderTransform_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Test obj = (Test)d; // my control
        Transform x = obj.RenderTransform; // new rendertransform
        if (x.IsFrozen == false)
        {
            x.Changed += obj.RenderTransform_Changed;
        }
        // do anything
    }

非常感谢。你的解决方案让我找到了正确的方向,但我用另一种方法解决了。我会把你的答案标记为正确的答案,我认为它也会起作用。当之无愧谢谢,谢谢。你的解决方案让我找到了正确的方向,但我用另一种方法解决了。我会把你的答案标记为正确的答案,我认为它也会起作用。当之无愧谢谢
    protected static void RenderTransform_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Test obj = (Test)d; // my control
        Transform x = obj.RenderTransform; // new rendertransform
        if (x.IsFrozen == false)
        {
            x.Changed += obj.RenderTransform_Changed;
        }
        // do anything
    }