繁体   English   中英

C# WPF 行为类,由于窗口缩放更改,UIElement 被卸载后,AssociatedObject 为空

[英]C# WPF Behavior class, AssociatedObject is null after the UIElement was unloaded due to windows scaling change

我是 WPF 的新手,正在尝试使用可拖动窗口修复错误。

我正在检查我维护的应用程序中的错误,其中我们有一个 Behavior 类,我们使用它实现了拖动机制。 当我转到 windows 的显示设置并更改缩放比例 (100%/125%/150%/175%) 时,windows 似乎处理应用程序的窗口并重新创建它。
这是行为类的 AssociatedObject 成员变为空的地方,因此当再次调用 Loaded 事件时,我没有 AssociatedObject 可以使用。

我怎样才能获得新的 AssociatedObject? 自从重新创建 UI 元素以来,这似乎是预期的行为,但行为类仍然“活着”但无法做任何工作,因为它不熟悉新的 UI 元素(如果我理解正确,正如我所提到的,我是 WPF 的新手)

谢谢!

编辑:添加示例类

public class SetWindowSizeBehavior : Behavior<FrameworkElement>
{

    protected override void OnDetaching()
    {
        Console.WriteLine("detaching");
        base.OnDetaching();
    }

    protected override void OnAttached()
    {
        AssociatedObject.Unloaded += AssociatedObject_Unloaded;
        AssociatedObject.Loaded += AssociatedObject_Loaded;

        base.OnAttached();
    }

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        Console.WriteLine("");
        var a = AssociatedObject;
    }

    private void AssociatedObject_Unloaded(object sender, RoutedEventArgs e)
    {
        Detach();
    }
}

在 Windows 显示设置菜单中更改缩放设置后,这是调用堆栈:
AssociatedObject_Unloaded
分离时
AssociatedObject_Loaded <- 这是 AssociatedObject 变为 null 的地方

我希望这个问题现在更清楚了,如果没有,希望得到一些关于丢失信息的评论......

您可以尝试覆盖“OnPropertyChanged”方法吗

public class SetWindowSizeBehavior : Behavior<FrameworkElement>
{

    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        base.OnPropertyChanged(e);
        if (AssociatedObject == null)
        {
            // so, let'save the value and then reuse it when OnAttached() called
            _value = e.NewValue as string;
            return;
        }

        if (e.Property == PasswordProperty)
        {
            if (!_skipUpdate)
            {
                _skipUpdate = true;
                AssociatedObject.Password = e.NewValue as string;
                _skipUpdate = false;
            }
        }
    }
    protected override void OnDetaching()
    {
        Console.WriteLine("detaching");
        base.OnDetaching();
    }

    protected override void OnAttached()
    {
        AssociatedObject.Unloaded += AssociatedObject_Unloaded;
        AssociatedObject.Loaded += AssociatedObject_Loaded;

        base.OnAttached();
    }

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        Console.WriteLine("");
        var a = AssociatedObject;
    }

    private void AssociatedObject_Unloaded(object sender, RoutedEventArgs e)
    {
        Detach();
    }
}

从这里: https : //stackoverflow.com/a/42312799/7779827

最终我使用了@DanielFr 的想法,当我检测到关联对象为空时(因为在调用 detach 方法时基类 Behavior 将其设置为空),我使用了发送者对象,并且:

if (AssociatedObject == null)
        {
            //If we got here then we didn't go through onAttached in this iteration
            Attach((FrameworkElement)sender);
        }

当 FrameworkElement 是我的行为类中的 T 时

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM