[英]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();
}
}
最终我使用了@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.