Reputation: 41
I would like to access my WPF element from a lambda expression.
Here is my simplified code:
public static class MyClass
{
public struct MyStruct
{
public Rectangle MyRectangle {get; set;}
public Button MyButton {get; set;}
public void MyVoid()
{
MyRectangle = new Rectangle();
MyRectangle.Width = 300;
MyRectangle.Height = 100;
MyGrid.Children.Add(MyRectangle);
MyButton = new Button();
MyButton.Widht = 200;
MyButton.Height = 200;
MyButton.Click += (a, e) =>
{
MyRectangle.Fill = Brushes.Red;
}
MyGrid.Children.Add(MyButton);
}
}
}
But there is an error with MyRectangle in "MyButton.Click" :
Anonymous methods, lambda expressions, and query expressions in structs cannot access instance members of "this".
Can someone explain how to fix this error?
Upvotes: 0
Views: 204
Reputation: 41
Your solution did not work for me. To solve the problem, I deleted the anonymous method and created another one outside of the "MyVoid" method.
Upvotes: 0
Reputation: 10035
The easy fix, as per @Sean said, change struct
to class
.
If it has to be struct
, you need to deference this
to a local variable:
MyStruct self = this;
MyButton.Click += (a, e) =>
{
// Assuming Rectangle here is System.Windows.Shapes.Rectangle
self.MyRectangle.Fill = Brushes.Red;
}
I can also give you some explanation about the error:
The error is because this
which is effectively ref this
in struct
is a pointer which cannot be captured and stored in Delegate.Target
.
In order to get this
captured by a delegate, you will need to dereference this
to a local variable and capture the value in the variable.
However, when you do the above, the compiler creates a defensive copy, meaning self
is a copy of the struct where this
points to. This means, whilst you can still make changes to fields / properties whose return types are reference types, any changes made to self
instance itself as well as those value type returning fields / properties won't be reflected in this
.
Upvotes: 1