Reputation: 1009
I'm new to WPF, and trying to fix a bug with a draggable window.
I'm checking a bug in an app I maintain where we have a Behavior class, with which we implement a dragging mechanism.
When I go to windows' display settings and change the scaling (100%/125%/150%/175%), windows seems to dispose the app's window and recreate it.
This is where the AssociatedObject member of the behavior class becomes null, so when the Loaded event is invoked again, I have no AssociatedObject to work with.
How can I get the new AssociatedObject? It seems like expected behavior since the UI element was recreated, but the behavior class is still 'alive' but can't do any work since it isn't familiar with the new UI element (If I understand things correctly, as I mentioned, I'm new to WPF)
Thanks!
Edit: adding a sample class
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();
}
}
After I'm changing the scaling settings at the windows display settings menu, this is the call stack:
AssociatedObject_Unloaded
OnDetaching
AssociatedObject_Loaded <- this is where AssociatedObject becomes null
I hope the question is more clear now, and if not, would love to get some comments about missing info...
Upvotes: 0
Views: 1145
Reputation: 1009
Eventually I used @DanielFr's idea and when I detected that the associatedObject is null (cause the base class Behavior sets it to null when the detach method is called) I used the sender object and:
if (AssociatedObject == null)
{
//If we got here then we didn't go through onAttached in this iteration
Attach((FrameworkElement)sender);
}
When FrameworkElement is my T in my Behavior class
Upvotes: 0
Reputation: 111
Can you try overriding the 'OnPropertyChanged' method
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();
}
}
From here: https://stackoverflow.com/a/42312799/7779827
Upvotes: 1